代码之家  ›  专栏  ›  技术社区  ›  KooiInc

对象原型方法中私有变量的作用域

  •  1
  • KooiInc  · 技术社区  · 15 年前

    这个问题是关于对象的行为,对象的原型链中添加了方法和一些私有变量。只是出于好奇,想弄明白这个谜。

    function SomeObject() {
        if (this instanceof SomeObject) {
          var args  = arguments[0],
              proto = SomeObject.prototype,
              privatevalue = 0,
          /** assign first element of args[0] 
            * (=instance name) to private variable [id],
            * to be able to keep track of the instance
            */
              id = args[0] ||'no id';
    
    
          /** public 'set' adds a value to
            * the private variable [privatevalue]
            */
          this.set =
             function(){
               privatevalue += arguments[0] || 1;
               return privatevalue;
              };
           /** toString functions as a kind of getter */
           this.toString = function(){
                return id+' privatevalue: '+privatevalue;
           }
    
           /** add two methods to the prototype chain 
             * this happens only once
             */
           if (!proto._initialized_) {
             /** SomeObject.prototype.add 
               * uses 'this.set' to add a value
               * to [privatevalue] and returns
               * the object value (from tostring)
               */
             proto.add =
               function(){
                 this.set(arguments[0]);
                 return this;
             };
             /** SomeObject.prototype.add2 
               * uses 'this.set' to add a value
               * to [privatevalue] but returns
               * a string using private variables
               * [id] and [privatevalue] 
               */
             proto.add2 =
                function(){
                  this.set(arguments[0]);
                  return id+' privatevalue: '+privatevalue;
             };
             proto._initialized_ = true;
            }
    
            } else {
               return new SomeObject(Array.prototype.slice.call(arguments));
            }
      }
    
      /** create 2 instances of SomeObject */
      var objA = SomeObject('objA'),
          objB = SomeObject('objB');
    
      /** show the values and use the prototype [add] method
        * to change [privatevalue]
        */
      alert ([objA, objB].join(' | ')); 
            //=> objA privatevalue: 0 | objB privatevalue: 0
      alert ([objA.add(4), objB.add(2)].join(' | ')); 
             //=> objA privatevalue: 4 | objB privatevalue: 2
    
      /** use prototype method 'add2' to change and view the
        * private variables [id] and [privatevalue] for objA
        */
      alert (objA.add2()); 
             //=> objB privatevalue: 2!
    

    现在的问题是:为什么来自ojbA的原型方法add2(因此:objA.add2())从objB返回私有变量的值?我想说,奥布贾不应该接近这些私密处。换句话说:这里正在进行什么样的范围界定? 还是陌生人。如果您这样做:

      alert (objA.add2()); 
      alert (objB.add2());
    

    对于objA.add2(),您将获得: objA privatevalue: 5 objA私有值:5

    1 回复  |  直到 15 年前
        1
  •  1
  •   AnthonyWJones    15 年前

    问题在于创建add函数的范围。

    它们是在实例化“objA”时在SomeObject执行的范围内创建的。

    因此,Add2访问的id和privatevalue变量属于“objA”,而不管您是再次调用.Add2“objA”还是“objB”。