2011-12-08 20 views
191

Eventuali duplicati:
Understanding prototypal inheritance in JavaScriptQual è lo scopo del prototipo?

OK, quindi sono un po 'nuovo al concetto di programmazione orientata agli oggetti in JS.

Qual è la differenza tra questi due frammenti di codice scritto sotto:

function animal(){ 
    this.name = 'rover'; 
    this.set_name = function(name){ 
     this.name = name; 
    } 
} 
function animal(){ 
    this.name = 'rover'; 
} 
animal.prototype.set_name = function(name){ 
    this.name = name; 
} 

Entrambi fanno la stessa cosa, quindi qual è la differenza?

+0

membro a livello di istanza condiviso (non statico) per una classe. e.g) Person.prototype.instance_counter = 0; // Non è possibile accedere a ClassName come Person.instance_counter (Questo è statico). –

risposta

271

L'utilizzo del prototipo facilita la creazione di oggetti, poiché non è necessario ricreare la funzione ogni volta che viene creato un nuovo oggetto.

Quando si esegue questa operazione:

function animal(){ 
    this.name = 'rover'; 
    this.set_name = function(name){ 
     this.name = name; 
    } 
} 

La funzione set_name è creato de novo ogni volta che si crea un animale. Ma quando lo fai,

animal.prototype.set_name = function(name){ 
    this.name = name; 
} 

La funzione non deve essere ricreata ogni volta; esiste in un posto nel prototipo. Pertanto, quando si chiama someAnimal.set_name("Ubu"); il contesto this verrà impostato su someAnimal e verrà chiamata la (la sola e unica) set_name funzione.


C'è un vantaggio di utilizzare la prima sintassi però: funzioni create in questo modo avranno accesso a dati privati:

function animal(){ 
    var privateData = 'foo' 

    this.name = 'rover'; 
    this.set_name = function(name){ 
     this.name = name; 
     alert(privateData); //will alert 'foo' 
    } 
} 

Douglas Crockford chiama le funzioni create in questo modo "privilegiato" per questo motivo : hanno accesso a dati pubblici e privati.

28

La differenza appare quando si crea nuovo oggetto da queste funzioni

var animal1 = new animal(); 

Tutti gli oggetti creati dalla prima funzione avrà diverse name e set_name proprietà. Tuttavia, tutti gli oggetti creati dalla seconda funzione condivideranno la proprietà set_name.

19

Nel primo esempio, ciascun animale separato ha una propria proprietà per la funzione set_name, mentre nel secondo esempio condividono la stessa funzione tramite il proprio prototipo.

Il vantaggio della prima versione è che i metodi possono accedere a variabili locali (private) dichiarate all'interno del costruttore.

Il vantaggio del secondo metodo è che ha bisogno di meno memoria (poiché si memorizza il metodo una volta invece di un milione di volte) ed è più performante negli attuali motori JS.

Utilizzando il secondo metodo è inoltre possibile modificare o aggiungere metodi a una classe in un modo che influisce anche su istanze già create.