Frage

Diese Frage ist über das Verhalten eines Objekts mit Methoden zu dessen Prototyp-Kette und einigen privaten Variablen hinzugefügt. Nur aus Neugier und meinen Kopf zu bekommen, um dieses Rätsel.

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!

Nun ist die Frage: warum ist der Prototyp Methode add2 von ojbA (also: objA.add2 ()), die die Werte der privaten Variablen aus objB? Ich würde sagen, dass diese Soldaten nicht für objA zugänglich sein. Mit anderen Worten: welche Art von Scoping ist hier los? Noch merkwürdiger ist. Wenn Sie dies tun:

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

Sie erhalten für objA.add2 (): objA privatevalue: 5 und für objB.add (): objA privatevalue: 5

War es hilfreich?

Lösung

Das Problem ist der Umfang, in dem Sie die Add-Funktionen erstellen.

Sie werden im Rahmen der Ausführung Someobject erstellt, wenn Sie ‚objA‘ instanziiert.

Daher id und privatevalue von Add2 zugegriffen Variablen sind diejenigen, die zu ‚objA‘ unabhängig davon, ob Sie .Add2 agains ‚objA‘ nennen oder ‚objB‘.

Fundementally Prototyp basierte Methoden können keine privaten Mitglieder einer Klasse zuzugreifen. Braucht, um private Mitglieder Zugriff auf eine Funktion im gleichen Umfang (oder ein Kind scope) der Mitglieder geschaffen werden. Aus diesem Grunde Satz funktioniert, weil sein auf jeder instantiaion von Someobject erstellt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top