2012-08-14 8 views
5

dopo la mia ultima domanda, questo è più accurato per me:variabili “var”, "Questo" variabili e variabili "globali" - all'interno di un costruttore JavaScript

esempio:

function Foo() { 
    this.bla = 1; 
    var blabla = 10; 
    blablabla = 100; 
    this.getblabla = function() { 
     return blabla; // exposes blabla outside 
    } 
} 
foo = new Foo(); 

quello che ho capire ora:

this.bla = 1;  // will become an attribute of every instance of FOO. 
var blabla = 10; // will become a local variable of Foo(will **not** become an attribute of every instance of FOO), which could be accessed by any instance of FOO - only if there's a method like "this.getBlabla". that's a "closer" ? 
blablabla = 100; // will define a **new** (or change if exist) global(window) variable. 

Ho capito correttamente?

Inoltre, se includo lo var blabla = 10; e la funzione getblabla che lo utilizza nell'appaltatore, quindi per ogni istanza di Foo ("pippo" ...), nella memoria viene salvata una funzione appaltatore Foo che include questo variabile "privata". o sarà la stessa funzione Foo del posto per le variabili private - per le istanze ALL (come "foo") di Foo?

+0

Le tue prime tre asserzioni sono corrette. Non seguo completamente quello che chiedi per la tua ultima domanda. Puoi chiarire?Puoi provare anche variabili non nominate in modo simile? È difficile da seguire. Grazie. – Brad

+0

È complicato anche per me. Voglio dire - è una chiusura, giusto? ed è un appaltatore - quindi, per ogni istanza di Foo, ci sarà una nuova chiusura di Foo nella memoria? come funziona questa roba? Grazie. – Daniel

risposta

6

Basta mettere a fuoco il campo di applicazione, ho intenzione di correre attraverso questo esempio, (con più chiara variabili) Successivamente, lo collegherò alle tue variabili.

var x = "Global scope"; 
var y = "Not changed."; 

function Foo() { 
    this.x = "Attribute of foo"; 
    var x = "In foo's closure"; 
    y = "Changed!" 
    this.getX = function() { 
     return x; 
    } 
} 

// do some logging 

console.log(x); // "Global scope" 
console.log(y); // "Not changed" 
foo = new Foo(); 
console.log(y); // "Changed!" 
console.log(foo.x); // "Attribute of foo" 
console.log(x); // "Global scope" 
console.log(foo.getX()); // "In foo's closure" 

La linea: this.x è equivalente a this.bla, e definisce un attributo disponibile esternamente di un oggetto Foo. y equivale a blablabla=100 e quindi lo x all'interno di foo equivale al tuo blablabla all'interno di foo. Ecco un rozzo jsfiddle che puoi correre per vederlo.

1

Sì, lo capisci!
Per quanto riguarda la seconda parte della domanda, si tratta di ereditarietà, proprio come la relazione tra la finestra (globale) e le funzioni definite nel suo ambito (pensa come root). Quindi tutto ciò che non si ri-specifica, verrà esaminato dall'antenato.

Questo è un tremendous good video di Crockford, che lo spiega DAVVERO bene.

2

Tutto ciò che hai detto è corretto. (Naturalmente, un errore verrà lanciata contro l'assegnazione blablabla in Strict Mode.

Nella seconda metà, non c'è niente di speciale la funzione di costruzione. Si comporta come qualsiasi altra funzione in quanto crea una chiusura che persiste più a lungo . come il suo riferimento (la durata del this.getblabla in questo caso)

Prendete questo esempio:

function initBlaBla() { 
    var blabla = 10; 
    this.getblabla = function() { 
     return blabla; // exposes blabla outside 
    } 
} 

function Foo() { 
    this.bla = 1; 
    blablabla = 100; 
    initBlaBla.call(this); 
} 

foo = new Foo(); 

Qui, il costruttore Foo non forma una chiusura e la sua portata viene rilasciato immediatamente initBlaBla dall'altro. han d crea una chiusura. È interessante notare che il compilatore può vedere che blabla non viene mai scritto e ottimizzare this.getblabla per restituire sempre 10 e mai salvare l'ambito di chiusura. Questo può essere visto quando si interrompe l'esecuzione in una funzione all'interno di una chiusura e si prova a leggere un valore che non fa riferimento internamente.

L'ambito chiusura otterrà rilasciato e in coda per la raccolta dei rifiuti se si chiama una delle seguenti:

delete foo.getblabla; 
foo.getblabla = "Anything!"; 
foo = "Anything else.";