Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JS变量范围_Javascript_Scope - Fatal编程技术网

Javascript JS变量范围

Javascript JS变量范围,javascript,scope,Javascript,Scope,JS中的变量范围让我非常困惑。在下面的代码中,如果我使用setClientpublic方法设置clientID,那么我可以使用getClient方法从track方法内部访问该值。但是,我无法通过这种方式访问私有成员“版本”的值(或任何其他私有成员)。我假设var\u this=this将创建某种类型的闭包,允许访问容器函数的范围 现在我很困惑。我意识到这可能非常简单,所以我想在这里问一下。究竟哪里有人抓住了棍子的错误一端 function Container() { // private

JS中的变量范围让我非常困惑。在下面的代码中,如果我使用
setClient
public方法设置
clientID
,那么我可以使用
getClient
方法从track方法内部访问该值。但是,我无法通过这种方式访问私有成员“版本”的值(或任何其他私有成员)。我假设var
\u this=this
将创建某种类型的闭包,允许访问容器函数的范围

现在我很困惑。我意识到这可能非常简单,所以我想在这里问一下。究竟哪里有人抓住了棍子的错误一端

function Container()
{
    // private members
    var version = '0.1';
    var CID = false;
    var _this = this;
    
    // public members
    this.getVersion = function() { return _this.version; }
    this.getClient = function() { return _this.CID; }
    this.setClient = function(CID) { _this.CID = CID; }
    
    // private methods
    this.getQS = function() { return _this.version; }
    
    // public methods
    this.track = function()
    {
        if (_this.CID)
        {
            var date = new Date();
            
            data = 
            {
                cid: _this.getClient(),
                sw: screen.width ? screen.width : false,
                sh: screen.height ? screen.height : false,
                d: date.getTime()
            }
            
            qs = '';
            
            for (p in data) { qs += p+'~'+data[p]+'-'; }
            
            var elHd = document.getElementsByTagName("head")[0];         
            var elScr = document.createElement('script');

            elScr.type = 'text/javascript';
            elScr.src = 'http://example.org/'+qs+
                            'version-'+_this.getVersion();
            
            elHd.appendChild(elScr);
        }
        else
        {
            alert('no client ID');
        }
    }
}

我不确定我是否理解你在哪里感到困惑(或者你为什么这样做,所以我可能会感到困惑)。如果你只是这样做会发生什么:

this.getVersion = function() { return version; }
变量版本不是容器类的成员字段。它是一个仅在容器构造函数期间存在的局部变量。您需要这样创建它(就像您使用这些方法一样):


您应该对CID字段执行相同的操作。更好的是,将它们添加到类的原型对象中。

稍微清理一下容器构造函数。 version和CID变量是私有的,并且在容器构造函数作用域内,因此您不需要this scope引用,它根本不起作用。这公共可访问的属性和方法需要引用,在构造函数之外定义原型时非常有用,如第二个代码块所示

function Container() {
  var version = "0.1", CID = false;

  this.getVersion = function()      { return version };
  this.getClient  = function()      { return CID     };
  this.setClient  = function(value) { CID = value    };

  this.track = function() {
    if (CID) {
      var qs = "", data = {
        cid: this.getClient(),
        sw: screen.width ? screen.width: false,
        sh: screen.height ? screen.height: false,
        d: (new Date).getTime()
      };
      for (var p in data) qs += p +"~"+ data[p] +"-";
      var js = document.createElement("script");
      js.type = "text/javascript";
      js.src = "http://example.org/"+ qs +"version-"+ this.getVersion();
      document.getElementsByTagName("head")[0].appendChild(js);
    } else {
      alert("No Client ID");
    }
  };
};
这个。在构造函数之后添加/重写原型时,引用变得至关重要

function Container2() { }
Container2.prototype = {
  CID: null,
  version: "0.1",
  track: function() {
    alert(this.version);
  }
}

简单的答案是使用

this.getVersion = function() { return version; }
因为JavaScript函数是对version的引用,所以即使在函数返回后,也可以访问上面函数中的局部变量。试图访问
\u此。版本
是试图读取
\u此
对象的版本成员。由于您从未将
分配给此
版本成员,因此它将返回
未定义的值

在JavaScript中,您只能访问显式添加到您正在使用的对象、添加到该对象的原型或原型的原型等的成员


道格拉斯·克罗克福德(Douglas Crockford)的一篇优秀文章中提供了有关在JavaScript中使用私有成员的更多信息:

非常感谢。很明显,我是在错误的印象下工作的,我需要创建一个闭包或某种反向引用。我想这又回到了奥莱利关于美诺问题的书上,你需要花点时间来思考它。正如在这里的另一篇文章中所提到的,这是一本很好的读物,有助于巩固它的工作原理。
this.getVersion = function() { return version; }