JS可变范围

时间:2009-03-23 19:49:04

标签: javascript scope

JS中的变量范围让我感到困惑。在下面的代码中,如果我使用setClient公共方法来设置clientID,那么我可以使用getClient方法从track方法内部访问该值。然而,我不能以这种方式(或任何其他私有成员)访问私有成员'版本'的值。我假设var _this =这将创建某种类型的闭包,允许访问Container函数的范围。 / p>

现在我很困惑。我意识到这可能很简单,所以我想我会问这里。在地球上有没有抓住棍子的错误端?

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');
        }
    }
}

4 个答案:

答案 0 :(得分:1)

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

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);
  }
}

答案 1 :(得分:0)

我不确定我是在理解你感到困惑的地方(或者你为什么按照自己的方式做事,所以我可能会感到困惑)。如果您这样做会发生什么:

this.getVersion = function() { return version; }

答案 2 :(得分:0)

变量 version 不是Container类的成员字段。它是一个局部变量,仅在Container构造函数的持续时间内存在。你需要创建它(就像你使用的方法一样):

this.version = "0.1";

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

答案 3 :(得分:0)

简单的答案是使用

this.getVersion = function() { return version; }

因为JavaScript函数是对 version 的引用的闭包,所以即使在函数返回后,也可以访问上面函数中的局部变量。尝试访问 _this.version 是尝试阅读 _this 对象的版本成员。由于您从未分配 _this 版本成员,因此将返回未定义的值。

在Javascript中,您只能访问明确添加到您正在使用的对象,或添加到该对象的原型或原型的原型等的成员。

有关使用私有成员使用JavaScript的更多信息,请参阅Douglas Crockford撰写的精彩文章:Private Members in JavaScript