Pregunta

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

Tengo problemas con la configuración de la herencia prototípico en javascript. Lo ideal sería que yo quiero tanto thing1 y thing2 a tener su propia copia limpia del "nuevo prototipo Entidad".

usando this.__proto__ es algo que quiero evitar

[Editar]

Tengo una idea aproximada de cómo este trabajo.

Configuración thing1.b establece la propiedad b en la instancia cosa. que no toca el Entity.b se define en la cadena de prototipo.

Cuando, como el establecimiento de thing1.a.a en la instancia cosa no puede se ha hecho porque sería lanzar una "no puede establecer una en indefinido" de error. Que de cuando sube la cadena de prototipo para encontrar Entity.a que se define y establece Entity.a.a a un nuevo valor.

[Además Editar]

Como dice @IvoWetzel establecer thing1.b no toca la cadena de prototipo debido a la configuración de propiedades no lo hace. Donde como el establecimiento de thing1.a.a hace dos pasos. A getter en thing1.a que toca la cadena de prototipo seguido de un setter de .a

¿Fue útil?

Solución

Una cosa que podría hacer es Aplicar la lógica de su constructor Entity dentro Thing, por ejemplo:

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

Otros consejos

Mientras que la CMS ha publicado una solución, ¿por qué thing2.b retorno 5 y por qué lo hace la determinación thing2.a.a al objeto?

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

Todo el problema es acerca de JavaScript subiendo por la cadena de prototipo con el fin de encontrar propiedades. Sin embargo, cuando se establece que las propiedades no a subir la cadena.

Esto se debe a objetos JavaScript se trató siempre como referencia.

Por lo tanto, cuando se cambia el objeto this.a haciendo a.a.a = 3; que va a modificar un objeto en la memoria. Nuevas instancias de Thing harán referencia a ese mismo objeto en la memoria porque el constructor Entity no se llama cada vez que es Thing, y el objeto this.a sigue siendo el mismo.

Me pondría this.a fuera de la cadena de prototipo, probablemente directamente dentro del constructor Thing. Esto haría de manera que una nueva versión de this.a se crea en la memoria cada vez que se crea una instancia Thing.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top