2010-07-28 12 views
8

Tengo dificultades para entender la diferencia de los siguientes 2 conjuntos de códigos. El código original es de the famous Ninja tutorial y he simplificado un poco para mí.JavaScript: asignación de propiedad a través del prototipo

Pregunta: Creo que entiendo cómo funciona CodeA. Ninja.prototype.swung = false está asignando una nueva propiedad en function Ninja(), y ninjiaA.swung se evalúa como falso debido a eso. Sin embargo, en CodeB, cuando declaramos el function Ninja() con this.swung = true al principio, la asignación posterior de Ninja.prototype.swung = false no surte efecto, y ninjaA.swung queda por evaluar en verdadero. No entiendo por qué esta asignación posterior no funciona en CodeB. ¿Podría alguien por favor aclararme sobre esto?

CodeA:

function Ninja(){} 
Ninja.prototype.swung = false; 
var ninjaA = new Ninja(); 
ninjaA.swung; //evaluates to false 

CodeB:

function Ninja(){ 
    this.swung = true; 
} 
Ninja.prototype.swung = false; //I'm expecting this changes swung to false, 
           //but it doesn't. 
var ninjaA = new Ninja();  
ninjaA.swung; //evaluates to true 

Muchas gracias por adelantado.

Respuesta

15

Cuando declara una propiedad usando this dentro de la función constructora, se adjunta a cada objeto de ese constructor.

Cuando declara una propiedad en el prototipo de esa función de constructor, permanece allí y todos los objetos de ese constructor se refieren a ella. Cuando tiene una propiedad con el mismo nombre en el objeto y en la cadena del prototipo, la propiedad del objeto oculta la del prototipo.

Piense cómo se evalúa la propiedad en la cadena de prototipos que podría aclarar las cosas.

CodeA:

 
ninjaA.swung 

1. Is swung a property of the current object - No 
2. Is swung a property of the current object's prototype - Yes 
    2.1. Return it 

CodeB:

 
ninjaA.swung 

1. Is swung a property of the current object? - Yes 
    1.1 Return it 

En el código B, que nunca llega a la propiedad en el prototipo.

+2

+1 - muy bien presentado! –

+0

Edité tu respuesta para usar la etiqueta 'pre'. Encuentro el color casi humorístico para restar valor a la calidad de la respuesta. – ChaosPandion

+0

@ Dan - gracias :) @ ChaosPandion - gracias por el cambio, se ve mucho mejor ahora :) – Anurag

6

Al llamar al Ninja como constructor, asigna el valor true al swung. Antes de ejecutar el constructor del objeto se verá así:

{ 
    prototype : { 
     swung : false 
    } 
} 

Después se ejecuta el constructor:

{ 
    prototype : { 
     swung : false 
    }, 
    swung : true 
} 

Cuando se le pregunta por la propiedad swung la cadena de prototipo se comprobará en cada nivel para ver si existiera. Si no existe, se devolverá el valor undefined.

+1

+1 sus nuevas incorporaciones dejan en claro lo que está sucediendo. – Anurag

+1

@Anurag - Gracias, creo que su forma de explicarlo paso a paso ayudará a un novato a entenderlo mejor. – ChaosPandion

3

En JavaScript, el método adjunto al prototipo solo se invoca si el método no se encuentra primero en la instancia.

Cuestiones relacionadas