2010-10-10 9 views
4

Je trouve le comportement de ce morceau de code énigmatique, pourquoi est le constructeur de child pas Child? Quelqu'un pourrait-il me l'expliquer?le modèle d'objet javascript: étrange constructeur propriété

function Parent() { 
    this.prop1 = "value1"; 
    this.prop2 = "value2"; 
} 

function Child() { 
    this.prop1 = "value1b"; 
    this.prop3 = "value3"; 
} 
Child.prototype = new Parent(); 

var child = new Child(); 

// this is expected 
console.log(child instanceof Child); //true 
console.log(child instanceof Parent); //true 

// what?? 
console.log(child.constructor == Child); //false 
console.log(child.constructor == Parent); //true 
+0

Cette question semble être un dup de [celui-ci] (http://stackoverflow.com/questions/2479349/constructors-and-inheritance-in-js) - mais je trouve les réponses à cette question plus utiles. + 1s tout autour :) –

Répondre

5

Comme Pointy a souligné, in his answer

La propriété « constructeur » est une référence à la fonction qui a créé prototype de l'objet, et non l'objet lui-même.

La façon habituelle de traiter ce problème est d'augmenter prototype constructor propriété de l'objet après l'attribution à la prototype

function Parent() { 
    this.prop1 = "value1"; 
    this.prop2 = "value2"; 
} 

function Child() { 
    this.prop1 = "value1b"; 
    this.prop3 = "value3"; 
} 
Child.prototype = new Parent(); 

// set the constructor to point to Child function 
Child.prototype.constructor = Child; 

var child = new Child(); 

// this is expected 
console.log(child instanceof Child); //true 
console.log(child instanceof Parent); //true 

// corrected 
console.log(child.constructor == Child); // now true 
console.log(child.constructor == Parent); // now false 

console.log(Child.prototype.constructor); // Child 
console.log(Parent.prototype.constructor); // Parent 

Je ne peux pas recommander de Stoyan Stefanov Object Oriented JavaScript qui couvre Prototype et héritage en détail (Procurez-vous la deuxième édition si vous le pouvez car elle répond à certaines critiques de la première édition).

+0

merci pour le pourboire, peut-être que je vais le commander, même si la 2ème édition ne semble pas encore prête. – einarmagnus

+1

cette solution signifie que si je devais créer un frère de Child, c'est une autre 'fonction sibling() {}; Sibling.prototype =/* expression * /; var sibling = new Sibling() ', alors' expression' devrait être 'new Parent()' et pas le même objet parent que Child, c'est-à-dire 'Child.prototype! = Sibling.prototype'. Est-ce ainsi que cela se fait habituellement? J'aime la philosophie de l'héritage prototypique mais cela semble être une manière très compliquée de le faire. – einarmagnus

+0

Oui, vous ne pouvez pas affecter la même instance de 'Parent' au' prototype' de 'Child' et' Sibling' car toute modification du 'prototype' de Child ou de Sibling affectera l'autre. Par exemple, définir le 'constructor' de l'un le changera pour les deux. –

4

La propriété « constructeur » est une référence à la fonction qui a créé prototype de l'objet, et non l'objet lui-même.

+0

qui dans ce cas vient de l'objet retourné par la fonction constructeur 'Parent' et affecté au' Child.prototype' –

+0

Droite, exactement. J'ai essayé de trouver un site/blog que j'ai lu il y a quelques mois qui avait une bonne explication (avec de bons diagrammes), et si je le fais je le lierai. – Pointy

+0

non, l'objet lui-même est 'enfant', mais il a été construit par' Child' (notez la lettre majuscule). Cela ressemble à un (autre) défaut de conception de JS qui indiquerait le constructeur du prototype de l'objet et non le constructeur de l'objet. – einarmagnus

Questions connexes