2012-08-22 10 views
5

Tengo el siguiente código:¿Por qué cambiar el prototipo no afecta a los objetos creados anteriormente?

var A = function() {}; 
var a = new A(); 
var b = new A(); 
A.prototype.member1 = 10; 

A.prototype = {} 
var c = new A(); 
console.log(a.member1); 
console.log(a.constructor === b.constructor); 
console.log(a.constructor === c.constructor); 
console.log('---------'); 
console.log(c.member1); 

Es salida es:

10 
true 
false 
--------- 
undefined 
undefined 

El prototipo de a y b no ha cambiado y c tenían una nueva. ¿Tengo razón en que esto fue causado por el hecho de que a.constructor no es igual a c.constructor y cada uno de ellos tenía prototype? ¿Hay otros circs cuando los constructores de dos objetos pueden no ser iguales?

Pregunta adicional: ¿por qué se imprimieron dos cadenas undefined? (Cromo)

+0

¿Se supone que 'a1' es' c'? –

+0

Lo siento, mi error. Corregido;) –

+3

¿Estás en Chrome? Si es así, 'console.log (undefined)' registrará dos cosas: el 'undefined' registrado y el' undefined' devuelto. – pimvdb

Respuesta

5

En el momento que está llamando

var a = new A(); 

básicamente esta asignación se realiza:

a.__proto__ = A.prototype; 

A continuación, vuelva a asignar los A.prototype a un nuevo objeto, por lo c obtiene {} como su prototipo.

A.prototype = {}; 
var c = new A(); 

Sin embargo, esto no destruye la vieja A.prototype objeto - a.__proto__ todavía está apuntando a la misma.

¿Tengo razón en que esto fue causado por el hecho de que a.constructor no es igual a c.constructor y cada uno de ellos tenía un prototipo propio?

.constructor es básicamente una propiedad de conveniencia. No tiene ningún efecto sobre cómo se comportan las instancias.

Pregunta adicional: ¿por qué se imprimieron dos cadenas indefinidas?

No en mi consola, no lo hacen! (Opera 12)

2

Cuando crea un objeto, el prototipo del constructor se asigna a la propiedad __proto__ del nuevo objeto. Estás a continuación, cambiar el prototipo, pero las dos a y b objetos ya está señalando la referencia original:

var a = new A(); 
// a.__proto__ == A.prototype == {} (soon == {member1:10}) 
var b = new A(); 
// b.__proto__ == A.prototype == {} (soon == {member1:10}) 

A.prototype = {} // this changes A.prototype, but not a.__proto__ or b.__proto__ 
var c = new A(); // c.__proto__ = {} 

su primera undefined es de c.member1. El segundo es el cromo diciendo toda su declaración no tenía valor de retorno

1

La respuesta está en esta línea de código:

A.prototype = {} 

Cuando se llega a esta línea de código, en realidad está creando un NUEVO OBJECT en la memoria que es {}. Crear cualquier objeto nuevo utilizando A como su constructor señalará este OBJETO NUEVO como el prototipo.

Sin embargo, el PROTOTYPE VIEJO todavía existe en la memoria. Es solo que A.prototipo ya no apunta a eso. Cualquier objeto que crees usando A como constructor antes de redefinir la referencia de prototipo de A todavía apunta hacia este VIEJO PROTOTIPO ya que es un prototipo.

Cuestiones relacionadas