определение области действия частных переменных в методах прототипа объекта - PullRequest
1 голос
/ 24 февраля 2009

Этот вопрос касается поведения объекта с методами, добавленными в цепочку его прототипов, и несколькими личными переменными. Просто из любопытства и чтобы разобраться с этой загадкой.

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!

Теперь возникает вопрос: почему метод-прототип add2 из ojbA (то есть: objA.add2 ()) возвращает значения приватных переменных из objB? Я бы сказал, что эти рядовые не должны быть доступны для objA. Другими словами: что за вид деятельности здесь происходит? Еще незнакомец. Если вы сделаете это:

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

вы получите для objA.add2 (): objA privatevalue: 5 и для objB.add (): objA privatevalue: 5

1 Ответ

1 голос
/ 24 февраля 2009

Проблема в том, что вы создаете функции добавления.

Они создаются в области выполнения SomeObject при создании экземпляра objA.

Следовательно, переменные id и privatevalue, к которым обращается Add2, принадлежат objA независимо от того, вызываете ли вы .Add2 против objA или objB.

Методы, основанные на прототипах, не могут получить доступ к закрытым членам класса. Чтобы получить доступ к закрытым элементам, необходимо создать функцию в той же области (или дочерней области) этих элементов. Вот почему набор работает, потому что он создается в каждом экземпляре SomeObject.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...