2011-01-30 15 views
30

Mi rendo conto che questo è stato chiesto centinaia di volte, però, io non riesco a cogliere il concetto di "perché" prototipi in JavaScript sono propri, come apposto a imitare le classi (sì , So che JavaScript è un linguaggio basato su prototipi - ho raccolto così tanto).Cercando di capire il punto di prototipi in JavaScript

Come molte altre persone che cercano di rendere JavaScript un linguaggio quotidiano che uso, sono abituato al normale stile di classe OOP, come ho giocato in Java (e ho usato classi in ActionScript e PHP). Tuttavia, mentre I penso Capisco come funzionano i prototipi, non riesco a capire perché sono necessari.

Ecco il mio script di esempio di come sto attualmente comprendere prototipi in JavaScript:

var Apple = function() { 
    // An apple? 
}; 

Apple.prototype.color = "red"; 

Apple.prototype.changeColor = function(new_color) { 
    this.color = new_color; 
}; 
Apple.prototype.getColor = function() { 
    alert('color: '+this.color); 
}; 

var apple1 = new Apple(); 
var apple2 = new Apple(); 
apple2.changeColor("green"); 
apple1.getColor(); 
apple2.getColor(); 

... Avevo pensato che forse il prototipo significava che condivideva lo stesso oggetto invece di creare un nuovo oggetto ogni volta - tuttavia, ovviamente non è il caso poiché entrambi apple1 e apple2 hanno colori diversi, ancora (dopo aver eseguito la sceneggiatura).

Poi ho scritto in ciò che è più di uno script orientato agli oggetti:

var Apple = function() { 
    this.color = "red"; 

    this.changeColor = function(new_color) { 
     this.color = new_color; 
    }; 
    this.getColor = function() { 
     alert('color: '+this.color); 
    }; 
}; 

var apple1 = new Apple(); 
var apple2 = new Apple(); 
apple2.changeColor("green"); 
apple1.getColor(); 
apple2.getColor(); 

con gli stessi risultati (come previsto). ... Perché quest'ultimo codice non è raccomandato? Non ho problemi a usare i prototipi (supponendo che li abbia usati correttamente), ma ho bisogno di capire il concetto di "perché".

... Qualsiasi aiuto?

risposta

31

... Avevo pensato che forse il prototipo significava che condivideva lo stesso oggetto invece di creare un nuovo oggetto ogni volta ...

Lo fa. C'è un oggetto prototipo che è condiviso tra tutte le istanze create dal costruttore.

... tuttavia, ovviamente non è il caso poiché entrambi apple1 e apple2 hanno colori diversi, ancora (dopo aver eseguito detto script).

Per alcuni tipi (per numero di esempio, booleano, null, undefined, o una stringa), quando si cambia una proprietà che esiste l'oggetto prototipo di via this.color per esempio, si creerà una proprietà color sull'istanza. Il prototipo rimane inalterato in modo che le nuove istanze abbiano il colore predefinito definito nel prototipo.

Se tu avessi aggiornato un membro di un array o un oggetto che è stato riferimento una proprietà dell'oggetto prototipo, il cambiamento sarebbe visto tra tutte le istanze.

... Perché quest'ultimo codice non è raccomandato?

Poiché si stanno costruendo nuove funzioni identiche con la creazione di ogni nuova istanza invece di condividere un'istanza delle funzioni tramite l'oggetto prototipo.


Per espandere un po 'di più, mi piacerebbe sottolineare che quando la funzione viene chiamata come costruttore utilizzando la parola chiave new, this nel costruttore è la nuova istanza. Quindi qualsiasi proprietà aggiunta a this viene aggiunta all'istanza.

var Apple = function() { 
     // Here "this" is the object being constructed. As such, we're adding 
     // a property "rotten" to every instance created 
    this.rotten = false; 
}; 

    // adding a "color" property to the prototype object 
Apple.prototype.color = "red"; 

    // set the property "color" on the instance to the value of "new_color" 
Apple.prototype.changeColor = function(new_color) { 
    this.color = new_color; 
}; 
    // first check to see if this instance has its own "color" property. If so, 
    // use it. If not, look at the prototype object to see if it exists. 
Apple.prototype.getColor = function() { 
    alert('color: '+this.color); 
}; 

// two new instances each have their own "rotten" property, and don't have a 
// "color" property. Both share the prototype object, so if "color" is 
// requested, it will come from there 
var apple1 = new Apple(); 
var apple2 = new Apple(); 

// This will add an "color" property to the "apple2" instance 
apple2.changeColor("green"); 

// Doesn't have a "color" property, so it looks to the prototype object 
apple1.getColor(); 

// Has a "color" property, so it uses that instead of the "color" on the prototype 
apple2.getColor(); 
+1

Questo ha davvero aiutato moltissimo; grazie. Facendo riferimento a "Apple.prototype.color", posso vedere che è ancora "rosso", che riconferma il mio pensiero originale sui prototipi che fanno riferimento a un singolo oggetto. È ancora un po 'di confusione, dato che voglio specificare i miei metodi direttamente in ... beh, funzioni, ma penso che potrei esserne preso. Grazie ancora. – clicheName

+0

@clicheName: prego. Ho aggiornato con un po 'di informazioni in più, ma sembra che tu abbia capito. – user113716

+0

sto comprendendo correttamente? Sento, sono in qualche modo come variabili statiche e metodi in java che sono condivisi tra gli oggetti ... – Vishwanath

5

prototipo consente di aggiungere metodi e proprietà per una classe e si applicherà non solo alla classe, ma anche tutte le istanze di oggetti attuali di quella classe.

+0

Semplice spiegazione che rende chiaro. –

Problemi correlati