7

que estaba leyendo en Javascript jardín http://bonsaiden.github.com/JavaScript-Garden/ acerca prototipo en JavaScript y una de su ejemplo dice así:por qué funciona la lista el constructor real de una clase en javascript importante

function Foo() { 
    this.value = 42; 
} 
Foo.prototype = { 
    method: function() {} 
}; 

function Bar() {} 

// Set Bar's prototype to a new instance of Foo 
Bar.prototype = new Foo(); 
Bar.prototype.foo = 'Hello World'; 

// Make sure to list Bar as the actual constructor <------------------- 
Bar.prototype.constructor = Bar; 

Aviso la línea que dice Asegúrese de lista Bar como el constructor real. Realmente estoy perdido acerca de lo que hace/es. He intentado crear nuevas instancias de Bar() con y sin la última línea. Pero llamar "valor" o "método" en esas instancias devuelve exactamente las mismas cosas. Entonces me pregunto, ¿cuál es la necesidad (supongo que debe haber uno) de especificar el constructor?

Gracias!

Respuesta

6

Cada función tiene una propiedad prototype, se asigna cuando se crea el objeto función, que apunta a un objeto de nueva creación que hereda de Object.prototype, y tiene una propiedad constructor, que simplemente apunta de nuevo a la propia función.

El objetivo de la propiedad prototype es proporcionar una forma de implementar la herencia, utilizando funciones de constructor. Cuando llama a una función con el operador new, creará un nuevo objeto que hereda de prototype del constructor.

Ahora, el propósito de la propiedad constructor es tener una manera de referirse de nuevo al constructor que ha creado un objeto, por ejemplo:

function Foo() {} 
// default value of the property: 
Foo.prototype.constructor == Foo; // true 

Esta propiedad se hereda por las "instancias" del Foo , para que pueda saber qué constructor se utilizó para crear un objeto:

var foo = new Foo(); 
foo.constructor == Foo; 

Si asigna un nuevo objeto para el prototipo de la función, esta relación se pierde:

function Bar() {} 
Bar.prototype = { inherited: 1 }; 

Bar.prototype.constructor == Bar; // false 
Bar.prototype.constructor == Object; // true 

Y afecta también las instancias de la función:

var bar = new Bar(); 
bar.constructor == Bar; // false 
bar.constructor == Object; // true 

Otro caso similar es cuando se tienen dos o más niveles de herencia utilizando constructores, la forma más común se utiliza para denotar la relación de herencia entre las funciones, es asignar la propiedad prototype del segundo nivel, por ejemplo:

function Parent() {} 

function Child() {} 
Child.prototype = new Parent(); 

El código anterior tiene varios problemas, en primer lugar, se ejecuta la lógica del constructor de matriz para crear la relación de herencia, pero eso es otra historia, en el ejemplo anterior también se ve afectada la propiedad constructor, ya que reemplazamos Child.prototype por completo el objeto:

var child = new Child(); 
child.constructor == Parent; // true 

Si reemplazamos reemplazar el valor de la propiedad constructor de Child.prototype después asignarlo, se mostrará el comportamiento esperado:

function Child() {} 
Child.prototype = new Parent(); 
Child.prototype.constructor = Child; 

var child = new Child(); 
child.constructor == Child; // true 
+0

Gracias por una explicación tan detallada. Todo tiene sentido. Lo único que todavía me molesta pero puedo pasar por alto es que se ve un poco circular en el Child.prototype.constructor = Child –

+1

@Nik, ¡De nada! Sí, de hecho es circular por diseño, por ejemplo: 'Object.prototype.constructor.prototype.constructor.prototype.constructor == Object;' ;-) – CMS

2

Creo que esto tiene que ver con instanciar Bar con la nueva palabra clave. Creo que usar new buscará Bar.prototype.constructor. Antes de esa línea, el objeto vinculado a Bar.prototype.contructor es del tipo Foo, por lo que, al crear una instancia sin esa línea, formará un objeto Foo en lugar de un objeto Bar.

+0

Gracias Keith! ; Esa es una explicación sucinta y al punto también –

+1

¡De nada! Si esto te ayudó, ¿podrías +1? –

Cuestiones relacionadas