Domanda

function Entity() {
    this.a = {a: 4};
    this.b = 5;
}

function Thing() {}
Thing.prototype = new Entity;

var thing1 = new Thing;
thing1.a.a = 3;
thing1.b = 4;
var thing2 = new Thing;
console.log(thing2.a.a); // prints 3 instead of 4. I would like 4.
console.log(thing2.b) // prints 5 as wanted

Sto avendo difficoltà con l'impostazione ereditarietà prototipo in javascript. Idealmente voglio sia thing1 e cosa2 di avere la propria copia pulita del "nuovo prototipo Entità".

utilizzando this.__proto__ è qualcosa che voglio evitare

[Modifica]

ho una vaga idea di come questo lavoro.

Impostazione thing1.b imposta la proprietà B nell'istanza Thing. che non tocca l'Entity.b definito nella catena di prototipi.

Dove l'impostazione thing1.a.a nell'istanza cosa non può stato fatto perché sarebbe gettare un "non può impostare una su undefined" errore. Quel quando sale la catena di prototipi per trovare Entity.a che è definita e imposta Entity.a.a ad un nuovo valore.

[Ulteriori Modifica]

Come @IvoWetzel dice impostazione thing1.b non tocchi la catena di prototipi, perché l'impostazione delle proprietà non lo fa. Dove come impostazione thing1.a.a fa due passi. A getter su thing1.a che tocca la catena di prototipi seguito da un setter di .a

È stato utile?

Soluzione

Una cosa che potreste fare è quello di Applica la logica del costruttore Entity all'interno Thing, ad esempio:

function Entity() {
    this.a = {a: 4};
    this.b = 5;
}
Entity.prototype.c = 6;

function Thing() {
  Entity.apply(this, arguments); // ejecutes the assignments made in Entity
}
Thing.prototype = new Entity;

var a = new Thing;
a.a.a = 3;

var b = new Thing;
console.log(a.a.a); // 3
console.log(b.a.a); // 4

console.log(a.b);   // 5
console.log(b.b);   // 5

console.log(a.c);   // 6
console.log(b.c);   // 6

Altri suggerimenti

Mentre CMS ha pubblicato una soluzione, perché fa thing2.b ritorno 5 e perché fa thing2.a.a determinazione all'oggetto?

var thing1 = new Thing;

// thing1 has no a, but the prototype has so a.a is essentially the a of Entity
thing1.a.a = 3;

// Sets b on thing1, setting does not go up the prototype chain(!)
thing1.b = 4;  

// that's what thing1 looks like
Thing {proto: Entity { 
                      a: { <--- gets resolved 
                          a: 3 <-- gets set
                      }, 
                      b: 5
              },
              b: 4 <-- gets set directly
      }


var thing2 = new Thing;

// thing2.a does not exist, so we look up the prototype and find a on Entity
console.log(thing2.a.a); 

// thing2.b also does not exists, so once again we look up the prototype to find b on Entity
console.log(thing2.b);

// that's what thing2 looks like
Thing {proto: Entity {
                      a: {
                          a: 3 <- gets resolved
                      },
                      b: 5 <- gets resolved
              }
      }

Tutto il problema è su JavaScript risalendo la catena di prototipi al fine di trovare immobili. Ma quando si impostano le proprietà che non risalire la catena.

Questo perché gli oggetti JavaScript sono sempre trattati come riferimenti.

Quindi quando si cambia l'oggetto this.a facendo a.a.a = 3; stai cambiando che un oggetto in memoria. Nuove istanze di Thing farà riferimento che lo stesso oggetto in memoria perché il costruttore Entity non è chiamato ogni volta Thing è, e l'oggetto this.a rimane la stessa.

I avrebbe messo this.a al di fuori della catena di prototipi, probabilmente direttamente all'interno del costruttore Thing. Questo sarebbe fare in modo che una nuova versione di this.a viene creato in memoria ogni volta che viene creata un'istanza Thing.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top