2009-11-20 15 views
7

Che cos'è un prototipo per una classe JavaScript? In altre parole, qual è la differenza traCosa sono i prototipi in JavaScript?

Example.prototype.method {} 

e

Example.method{} 

quando si definisce la classe di esempio?

Edit: Per chi fosse interessato, ho trovato una grande spiegazione (in aggiunta alla risposta qui sotto) qui per la differenza tra metodi di classe e metodi costruttore: http://idhana.com/2009/07/13/constructor-vs-class-methods-in-javascript/

Edit 2: La risposta completa! http://blog.anselmbradford.com/2009/04/09/object-oriented-javascript-tip-creating-static-methods-instance-methods/

risposta

5

La differenza è nel secondo esempio che si sta creando un metodo statico, che non viene ereditato se Example è una funzione di costruzione. Definendo le proprietà nella proprietà prototype di una funzione di costruzione e creando oggetti con la parola chiave new, gli oggetti appena creati ereditano il prototipo del costruttore e quindi hanno accesso a tali metodi.

Un esempio potrebbe essere i metodi definiti nel built-in costruttori di base, come ad esempio String .. stringhe di nuova creazione hanno un metodo indexOf perché c'era quello definito nel prototipo della String funzione del costruttore

typeof String.prototype.indexOf // 'function' 

var name = 'John'; 
alert(name.indexOf('J')) // 0 

Il il codice seguente crea un costruttore di funzioni, prima definiamo un metodo statico, creiamo un oggetto, scopriamo che l'oggetto non ha un metodo getName, quindi ne definiamo uno nel prototipo e scopriamo che ora l'oggetto ha un metodo getName.

function Name(name) { 
    this.name = name; 
}; 
Name.getName = function(){}; 

var john = new Name(); 
typeof john.getName // undefined 

var john = new Name(); 
Name.prototype.getName = function(){ alert(this.name)}; 
typeof john.getName 

john.constructor.prototype.getName == john.getName // true 

Quindi, per ribadire, eredità in ECMAScript è ottenuta principalmente attraverso la definizione di proprietà/metodi nel prototipo di un costruttore di funzione, esempio potrebbe essere tutti i costruttori fondamentali come Data/Numero/String che hanno metodi definiti nella loro rispettive proprietà del prototipo, che consente di utilizzare tali metodi quando si crea un'istanza con la parola chiave new.

Ricordare che l'oggetto appena creato ha una proprietà constructor che punta al costruttore che lo ha creato e possiamo accedere direttamente alla proprietà prototype. L'oggetto john che abbiamo creato non possiede direttamente il metodo getName, poiché l'interprete non può trovarlo direttamente sull'oggetto che viaggia verso l'alto fino al costruttore e lo trova nel suo prototipo.

E btw, non abbiamo davvero dovuto creare una nuova istanza dell'oggetto john, come indicato nell'altra risposta è possibile definire le proprietà nel prototipo dopo aver creato il costruttore iniziale e tutti gli oggetti erediteranno tali prototipi proprietà anche dopo che sono state create.

Un metodo statico non può contare su contesto, non può contare su una specifica istanza di una classe, non può fare affidamento sulla parola this quindi questo non sarebbe un metodo statico:

function Name(name) { 
    this.name = name; 
    this.getName = function() { return this.name; } 
}; 

Questo sarebbe essere un esempio di un metodo statico:

Name.getName = function() {}; 

ma non c'è assolutamente alcun senso nel fare getName statica perché, come dice il nome si deve contare su un'istanza di oggetto per determinare ciò che la proprietà nome è, si dovrebbe avere più gener helper ic funziona come funzioni di analisi come Date.parse come metodi statici e definisce i metodi di istanza nel prototipo poiché sono più efficienti della definizione di this.foo = function(){} nel costruttore.

+0

quindi quando vorrei utilizzare Name.getName = function() {}? – sepiroth

+0

o meglio, quando potrei definire i metodi (e come) per la classe Name senza utilizzare la definizione del prototipo? – sepiroth

+0

'getName' sarebbe un metodo pubblico, quindi lo definisci sul prototipo piuttosto che statico, definiresti un metodo statico se non ci fosse lo scopo di renderlo pubblico o nel prototipo. –

2

Un prototipo è come una definizione di Classe, ma può essere modificato dinamicamente. Ogni volta che istanziate un oggetto di un certo tipo, utilizza il prototipo come modello.

Se si modifica un prototipo, gli oggetti di quel tipo avranno queste modifiche.