2011-06-29 11 views
6

Tengo este problema ... B es una clase base, y A es una clase derivada ... El evento A deriva de B, varios objetos de A apuntan al mismo objeto de B.Problema al extender la clase con el prototipo de objeto javascript

sé que he asignado un objeto de B para el prototipo de a a hacer que un niño de B.

Pero diferentes objetos de a, deben tener diferentes espacio de direcciones para mantener las variables, a la derecha ? ¿Alguien puede corregir esto?

function B(){ 

     this.obj = {}; 
    } 

    function A(){ 

    } 

    A.prototype = new B(); 

    var a = new A(); 
    var b = new A(); 
    var c = new A(); 

    console.log(a.obj == b.obj); //prints true 
    console.log(a.obj === b.obj); //prints true 

    a.obj.name = "stackoverflow"; 
    console.log(b.obj.name); //prints stackoverflow 

¿Qué cambio debo hacer en este código para que me dé el siguiente resultado.

a.obj === b.obj //must be false 

a instanceof A; //must be true 
a instanceof B; //must be true 
+1

¿Qué es exactamente lo que estás preguntando? ¿Cuáles son los problemas con el código que ha publicado o la diferencia en el comportamiento esperado? – Slavo

+0

Por favor, eche un vistazo, he corregido la pregunta ... –

Respuesta

4

Es por eso que no debe tener valores mutables (particularmente objetos o matrices) en un prototipo; el mismo valor se compartirá en todas las instancias de objetos y se puede cambiar en cualquiera de ellos. Aquí se puede evitar el problema mediante el uso de Object.create que no va a llamar al constructor de B al crear el prototipo:

A.prototype = Object.create(B.prototype); 

Constructor de A continuación, debe llamar al constructor de B para cada nuevo objeto:

function A() { 
    B.call(this); 
} 

Para navegadores que no son compatibles con Object.create() puede emularlo como se menciona en http://javascript.crockford.com/prototypal.html.

1

Esta es una parte de prototipos en Javascript, le sugiero que lea this excellent thread.

+0

Gracias por sus sugerencias ... –

2

Los valores se asignan por referencia, y como todas las instancias de A usan la misma instancia de B que su prototipo, todas se refieren a la misma 'B'.

Así que esto es exactamente lo que se espera aquí. Una forma de resolver esto, es agregar (por ejemplo) un método 'inicializar' la B 'clase', que luego podría llamar desde el constructor A.

También puede no usar 'new B()' para definir el prototipo y usar Object.create en su lugar. Object.create no llama al constructor de B, pero a continuación, puede llamar al constructor padre de A.

function A() { 
    B.call(this); 
} 
+0

Probé esto, mi segundo requisito no funciona aquí ... Es decir, una instancia de B == verdadero –

+0

Gracias funcionó ... –

0

Si quieres casos de A a tener una propiedad local de obj, añadir la propiedad a A, no B

function B(){ 
} 

function A(){ 
    this.obj = {}; // <<< this.obj here 
} 

A.prototype = new B(); 

var a = new A(); 
var b = new A(); 
var c = new A(); 

console.log(a.obj == b.obj); //=> prints false 
console.log(a.obj === b.obj); //=> prints false 

a.obj.name = "stackoverflow"; 
console.log(b.obj.name); //=> undefined 

otra manera de tener un local de obj viviendas en casos de A es utilizar un método de selección de B 's prototipo:

function B(){ 
    B.prototype.setObj = function(obj){ 
    this.obj = obj; 
    return this; 
    } 
} 
//... 
a.setObj({}).name = "stackoverflow"; 
console.log(a.obj.name); //=>prints stackoverflow 
console.log(b.obj.name); //=>undefined 
+0

Como dije, obj es propiedad de B, a la que se debe acceder desde la clase derivada A.¿Quieres decir que al derivar debería copiar todas las propiedades de B a A? –

+0

Si deriva 'obj' de' B' en 'A',' obj' es igual a todas las instancias de 'A' (su prototipo es' B'). Asi es como funciona. Sin embargo, puede declarar un método en el prototipo de B, estableciendo 'this.obj'. Ver mis ediciones – KooiInc

+0

Gracias por sus sugerencias ... –

Cuestiones relacionadas