2012-06-21 19 views
5

Sto cercando di capire le regole dell'ambito JavaScript. Quello che ho letto nei libri di testo e nella documentazione è confuso.Contesto di applicazione ed esecuzione JavaScript

Mi sembra che JavaScript sia un linguaggio con scope statico (o lessicale) - quando si tenta di associare un nome di variabile a una variabile (definizione), viene utilizzata la struttura lessicale del codice.

Un contesto di esecuzione sembra essere simile a uno stack frame nello stack di chiamate. Ogni contesto di esecuzione ha un oggetto variabile su cui sono definite tutte le variabili locali (della funzione associata). Questi oggetti variabili sono collegati insieme per fornire una "catena di portata" dall'oggetto variabile nella parte superiore dello stack all'oggetto variabile nella parte inferiore dello stack (l'oggetto finestra). Questa catena di portata viene cercata dall'alto verso il basso nei nomi di variabili vincolanti alle variabili. Questo è molto simile ai linguaggi con scope statico come C/C++/Java.

Sembra esserci una differenza importante rispetto a C/C++/Java - è possibile accedere a una variabile definita in una funzione il cui stack frame non è più nello stack di chiamate, come mostrato nell'esempio seguente:

var color = "red"; 
var printColor; 

function changeColor() { 
    var color = "green"; 

    printColor = function(msg) { 
     alert(msg + color); 
    } 
    printColor("in changeColor context, color = "); // "green" 
} 

changeColor(); 

// stack frame for "changeColor" no longer on stack 
// but we can access the value of the variable color defined in that function 

printColor("in global context, color = "); // "green" 

Ho capito bene? Ci sono altri problemi di cui dovrei essere a conoscenza?

Grazie in anticipo

+4

Un post molto completo ha colpito oggi HN che riguarda questo: [Qual è il contesto di esecuzione e Stack in JavaScript?] (Http://davidshariff.com/blog/what-is-the-execution-context-in- javascript /) –

+2

Questo è chiamato * chiusura *. La funzione assegnata a 'printColor' ha accesso a tutte le variabili definite in' changeColor' anche dopo la fine della funzione. Non so come sia in C. –

+0

@FelixKling quasi. tuttavia changeColor è definito anche in ambito globale, quindi il suo ambito non sarà mai raccolto. – webduvet

risposta

2

Questa è davvero una grande differenza tra C/C++ e JavaScript: JavaScript è un linguaggio garbage collection riferimento contati, il che significa che gli oggetti possono essere recuperati dal motore quando non hanno più alcun riferimento a loro. La funzione assegnata a printColor non è in pila, di per sé, poiché si trova in C o C++; viene assegnato dinamicamente e quindi assegnato a una variabile esterna all'ambito corrente. Così, quando il flusso di controllo ritorna da changeColor, la funzione anonima ha ancora un conteggio di riferimento di poiché l'esterno printColor riferisce ad esso, e quindi è utilizzabile dal ambito esterno.

Quindi, il tuo esempio non è tanto di un problema di scoping - è chiaro che si dichiara printColordi fuori della funzione ambito di changeColor. Quando si definisce changeColor, è closes il valore printColor nel nuovo ambito della funzione, rendendolo accessibile. Come combattimento detto, se si aggiunge un var alla seconda, la definizione interna di printColor, sarà shadow il primo printColor si dichiarò e non sarà accessibile al di fuori che la funzione blocco.

Per quanto riguarda altri problemi, sì, ce ne sono alcuni, ma vedere il mio commento sul tuo post originale per un buon inizio.

+0

Purtroppo potrei aver letto male la domanda (ad esempio la variabile 'color'), ma penso che ciò che ho scritto tenga ancora acqua. –

+0

Quando si dice che printColor non è in pila, presumo si intenda l'oggetto che rappresenta printColor. Quando viene chiamato printColor, il relativo contesto di esecuzione/stack frame viene inserito nello stack. O mi sono sbagliato? – asterix

0

Arriva sempre allo scope lessicale, che è funzione eseguita con la sua catena di ambito quando viene definita, non quando è invocata.

La funzione anonima è definita nell'ambito locale della funzione changeColor anziché nell'ambito globale.Quindi, quando viene eseguito di nuovo, stampa il colore verde che è elencato nello scope locale di function changeColor.

Problemi correlati