2014-11-19 14 views
10

Ich weiß, es funktioniert, aber ich weiß nicht warum und wie. Was sind die Mechaniken?Javascript Aufruf Eltern Konstruktor im Child (prototypische Vererbung) - Wie es funktioniert?

// Parent constructor 
function Parent(name){ 
    this.name = name || "The name property is empty"; 
} 

// Child constructor 
function Child(name){ 
    this.name = name; 
} 

// Originaly, the Child "inherit" everything from the Parent, also the name property, but in this case 
// I shadowing that with the name property in the Child constructor. 
Child.prototype = new Parent(); 

// I want to this: if I dont set a name, please inherit "The name property is empty" from the 
// Parent constructor. But I know, it doesn't work because I shadow it in the Child. 
var child1 = new Child("Laura"); 
var child2 = new Child(); 

//And the result is undefined (of course) 
console.log(child1.name, child2.name); //"Laura", undefined 

Ich weiß, was ich brauche, das call() oder die apply() Methode. Rufen Sie die "Superklasse" (die Parent Konstruktor) aus der Child, und übergeben Sie die this Objekt und das Argument name zu diesem. Es funktioniert:

function Parent(name){ 
    this.name = name || "The name property is empty"; 
} 

function Child(name){ 
    // Call the "super class" but WHAT AM I DO? How does it work? I don't understand the process, I lost the line. 
    Parent.call(this, name); 
} 

Child.prototype = new Parent(); 

var child1 = new Child("Laura"); 
var child2 = new Child(); 

console.log(child1.name, child2.name); // "Laura", "The name property is empty" 

Es funktioniert perfekt, aber ich verstehe nicht, was passiert. Ich habe die this in meinen Gedanken verloren, und ich kann den Prozess der call() Methode nicht folgen. Kopiert das den Konstruktorkörper von Parent zu Child oder was? Und wo ist das this Objekt? Warum funktioniert es?

Bitte helfen und beschreiben Sie den Prozess, ich verstehe nicht.

+0

dies sehen: http: //stackoverflow.com/questions/20830449/object-create-changes-prototype-constructor-to-parent-constructor-but-upon-chil –

+0

Verwandte https: // Stackoverflow. com/a/29543030/632951 – Pacerier

+0

Verstand, die Antwort zu akzeptieren? – plalx

Antwort

21

Zunächst einmal aufhören zu tun Child.prototype = new Parent(); für die Vererbung, es sei denn, Ihr Browser unterstützt keine andere Alternative. Das ist ein sehr schlechter Stil und kann unerwünschte Nebenwirkungen haben, da er tatsächlich die Konstruktorlogik ausführt.

Sie können jetzt Object.create in jedem modernen Browser verwenden.

Child.prototype = Object.create(Parent.prototype); 

Bitte beachten Sie, dass nach diesem Sie auch die constructor Eigenschaft Child.prototype beheben sollte, so dass es richtig Child Punkte statt Parent.

Child.prototype.constructor = Child; 

Als nächstes, wie funktioniert call? Nun kann call angeben, welches Objekt durch das Schlüsselwort this referenziert wird, wenn die Funktion ausgeführt wird.

function Child(name){ 
    //When calling new Child(...), 'this' references the newly created 'Child' instance 

    //We then apply the 'Parent' constructor logic to 'this', by calling the 'Parent' function 
    //using 'call', which allow us to specify the object that 'this' should reference 
    //during the function execution. 
    Parent.call(this, name); 
} 
+0

Diese Technik heißt "Konstruktor stehlen" – dgtc

+1

Um die vollständige Mechanik dieses/Konstruktors/Aufrufs zu demonstrieren, dass das OP neugierig auf w/r/t prototypische Vererbung war, würde ich sicherstellen, dass "Child.prototype.constructor = Child " nach der Zeile "Child.prototype = Object.create (Parent.prototype)". Wenn Sie das nicht tun, ist Child.prototype.constructor gleich Parent.prototype.constructor, was zu einigen unbeabsichtigten Konsequenzen führen wird - insbesondere. wenn Sie beginnen, Argumente und/oder Initialisierungsfunktionen hinzuzufügen, die spezifisch für den Kind-Konstruktor sind. Dieses Szenario wurde vom OP nicht explizit nachgefragt, aber es ist nützlich, es hervorzuheben. – herringtown

+1

Ich war mir dessen bewusst und normalerweise repariere ich das Konstruktormitglied, habe es aber für die Antwort nicht in Betracht gezogen. Es könnte aber trotzdem erwähnenswert sein. – plalx