2014-11-19 20 views
10

So che funziona, ma non so perché e come. Quali sono i meccanismi?JavaScript call Costruttore genitore nel bambino (eredità prototipica) - Come funziona?

// 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 

So quello che mi serve, il call() o il metodo apply(). Chiama la "super classe" (il costruttore Parent) da Child e passa l'oggetto this e l'argomento name a quello. Funziona:

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" 

Funziona perfettamente, ma non capisco cosa succede. Ho perso il this nella mia mente e non posso seguire il processo del metodo call(). Copia il corpo del costruttore da Parent a Child o cosa? E dov'è l'oggetto this? Perché funziona?

Si prega di aiutare e descrivere il processo, non capisco.

+0

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

+0

https Correlati: // StackOverflow. com/a/29543030/632951 – Pacerier

+0

La mente accetta la risposta? – plalx

risposta

21

Prima di tutto, smettere di fare Child.prototype = new Parent(); per ereditarietà, a meno che il browser non supporti altre alternative. Questo è uno stile molto pessimo e può avere effetti collaterali indesiderati, poiché in realtà esegue la logica del costruttore.

È possibile utilizzare Object.create in ogni browser moderno ora.

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

Si prega di notare che dopo questo si dovrebbe anche risolvere la proprietà constructor di Child.prototype in modo che punti correttamente per Child piuttosto che Parent.

Child.prototype.constructor = Child; 

Quindi, come funziona call? Bene call consente di specificare a quale oggetto verrà fatto riferimento la parola chiave this quando la funzione verrà eseguita.

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

Questa tecnica si chiama "constructor stealing" – dgtc

+1

Per dimostrare la meccanica completa di questo/constructor/call che l'OP era curioso sull'ereditarietà di w/r/t, mi sarei assicurato di aggiungere "Child.prototype.constructor = Child ;" dopo la riga "Child.prototype = Object.create (Parent.prototype)". A meno che tu non lo faccia, Child.prototype.constructor sarà uguale a Parent.prototype.constructor, il che porterà ad alcune conseguenze indesiderate - esp. se si inizia ad aggiungere argomenti e/o funzionalità di inizializzazione specifiche per il costruttore Child. Questo scenario non è stato esplicitamente chiesto dall'OP, ma è utile evidenziare .. – herringtown

+1

Ero consapevole di ciò e di solito aggiusto il membro del costruttore, ma lo considero al di fuori dell'ambito della risposta. Potrebbe valerne la pena, dopo tutto, comunque. – plalx