2012-01-31 18 views
21

Recentemente ho iniziato a leggere su OOP javascript e una cosa che gli autori sembrano saltare è quando un oggetto A è stato dichiarato e all'improvviso mi vedono "A.prototype.constructor = A; Per esempio,Perché utilizzare object.prototype.constructor in OOP javascript?

var A = function(){}; // This is the constructor of "A" 
A.prototype.constructor = A; 
A.prototype.value = 1; 
A.prototype.test = function() { alert(this.value); } 
var a = new A(); // create an instance of A 
alert(a.value); // => 1 

Così ho eseguire il comando in firebug "var a = function() {};". e poi "A.Constructor" che rivela è una funzione capisco questo
ho eseguito il codice "A.prototype.. costruttore = A; "e ho pensato che questo cambi il costruttore A da Funzione a A.

La proprietà del costruttore di A è stata modificata vero? Invece quando eseguo "A.constructor" mi dà ancora function().

Qual è il punto?

Vedo anche A.constructor.prototype.constructor.prototype .. cosa sta succedendo?

+6

Quali autori, dove? –

+0

Il codice da cui provengo è http://www.ruzee.com/blog/2008/12/javascript-inheritance-via-prototypes-and-closures – Matt

risposta

12

Se A ereditare B utilizzando A.prototype = new B();, è necessario reimpostare la proprietà costruttore per la classe A utilizzando A.prototype.constructor=A;, altrimenti le istanze di un dovrebbero avere un costruttore di B.

Nel tuo caso, A.prototype.constructor === A tornerà vero, così A.prototype.constructor = A non ha fatto nulla.

+0

Interessante quindi A.prototype.constructor = A; farebbe isolare se stesso da B? In questo modo, puoi estendere più proprietà usando A.prototype senza aggiungere ulteriori proprietà a B? – Matt

+0

Non si tratta di isolare, è solo assicurarsi che A abbia la giusta proprietà del costruttore. – xdazz

+11

Qual è lo scopo di avere la giusta proprietà del costruttore? Quando viene effettivamente consultato in pratica A.prototype.constructor? Non sembra influenzare il comportamento della creazione di nuove istanze di A, afaics. La risposta deve essere così ovvia che è generalmente non dichiarata, motivo per cui mi ha eluso :-) – Yetanotherjosh

4

È possibile verificare rapidamente che tale assegnazione supplementare non fa assolutamente nulla:

var A = function() {}; 
A.prototype.constructor === A; // true -- why assign then? 

Ripristino della proprietà constructor ha senso solo se avete assegnato un nuovo oggetto prototipo alla classe, sovrascrivendo il costruttore originale:

var A = function() {}; 
A.prototype = protoObject; // some object with members that you'd like to inherit 
A.prototype.constructor = A; // reset constructor 

Nel tuo caso, l'autore potrebbe farlo ciecamente come buona pratica, anche nei casi in cui non è necessario.

2

questo codice se spesso utilizzano in JS modello di ereditarietà classico (il codice è da schemi JavaScript da Stoyan Stefanov):

function inherit(C, P) { 
    var F = function() {}; 
    F.prototype = P.prototype; 
    C.prototype = new F(); 
    C.uber = P.prototype; 
    C.prototype.constructor = C; 
} 

per assegnare costruttore diritto alla classe figlia.

Nel tuo caso non ha fatto nulla, dal A.prototype.constructor === A prima dell'assegnazione.

1

Si potrebbe desiderare di vedere la mia risposta alla domanda simile:

https://stackoverflow.com/a/19616652/207661

TL; DR: il costruttore non è una proprietà di un'istanza. Per far sì che le cose sembrino coerenti, l'interprete JavaScript deve impostare prototype.constructor per funzionare da solo. Questa funzione può essere utilizzata in funzioni che operano genericamente su molti tipi diversi di oggetti.

1

Secondo MDN, Tutti gli oggetti ereditare una proprietà constructor da loro prototipo:

Example 1: 
var o = {}; 
o.constructor === Object; // true 

..

Example2: 
function Tree() { 
}  
var theTree = new Tree(); 
console.log(theTree.constructor === Tree); // true 

In fase di runtime, non fa alcuna differenza in base al valore della proprietà del costruttore.

Tuttavia, poiché la proprietà del costruttore restituisce un riferimento alla funzione Oggetto che ha creato il prototipo dell'istanza, è necessario reimpostare la proprietà del costruttore quando assegnano un nuovo prototipo alla funzione Oggetto.

var Forest = function() {}; 
Forest.prototype = theTree; 
console.log(new Forest().constructor === Tree); // true 
Forest.prototype.constructor = Forest; 
console.log(new Forest().constructor === Forest); // true 

https://jsfiddle.net/j1ub9sap/

Per ulteriori dettagli: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor

+0

Ciao, salgo sul tuo commento alcuni mesi dopo perché non capisco questa frase: "Tuttavia, come la proprietà del costruttore restituisce un riferimento alla funzione Oggetto che ha creato il prototipo dell'istanza " La funzione Oggetto non crea il prototipo dell'istanza, crea direttamente l'istanza no? Cosa significa esattamente? Grazie – jobou

+0

Significa che Se Forest eredita la Pietra usando Forest.prototype = new theTree(), le istanze di Forest avranno un costruttore dellaTree. Per avere Forest come costruttore, è necessario reimpostare la proprietà del costruttore per Forest utilizzando Forest.prototype.constructor = Forest. –

+0

Capisco il tuo esempio. La mia domanda riguardava più la documentazione ufficiale: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor Si dice "Restituisce un riferimento alla funzione Object che ha creato l'istanza prototipo.". Tuttavia tutti gli esempi in questa pagina non hanno il loro prototipo sovrascritto. Non esiste un'eredità personalizzata: 'var a = []; a.constructor === Array; 'Allora perché non dice che" il costruttore è il riferimento alla funzione Object che ha creato l'istanza stessa "? Grazie – jobou