2010-07-27 21 views
7

Qualcuno può dirmi perché l'ultima registrazione di 'x' è uguale a 0 e non 1. Ho pensato perché è dichiarata al di fuori di una funzione ha portata globale e quindi nella funzione il suo valore è impostato a 1 e quel valore rimarrebbe dato che è globale? So che il primo valore "x" all'interno della funzione è globale poiché qualsiasi variabile dichiarata senza la parola chiave var diventa una proprietà dell'oggetto window. Molte grazieE pensavo di aver compreso lo scope

var x = 0; //global variable 

function y(){ 
    x = 1; 
    log("1. %n ", x);//1. 1 

    var x = 2; 
    log("2. %n ", x);//2. 2 
} 

y(); 
log("3. %n ", x);//3. 0 

risposta

6

La dichiarazione var è oggetto di sollevamento, quando il codice viene valutata in realtà assomiglia a questo:

var x = 0; //global variable 
function y(){ 
    var x; // local!! 

    x = 1; 
    log("1. %n ", x);//1. 1 

    x = 2; 
    log("2. %n ", x);//2. 2 
} 

y(); 
log("3. %n ", x);//3. 0 

Poco prima y viene eseguito, un nuovo contesto di esecuzione è configurato, e il processo di Variable Instantiation prende inserire prima dello la funzione viene eseguita.

Questo è uno dei motivi per cui JSLint raccomanda solo una dichiarazione var per funzione, per assomigliare a ciò che sta effettivamente accadendo.

+0

Grazie amico. Puoi sempre rispondere a te per la risposta. – screenm0nkey

+0

Siete i benvenuti @Nick, sono felice di aiutare! – CMS

1

ho penso, ma non posso confermare tramite le specifiche ECMAScript, che il "var x = 2" riga viene esaminata al momento definizione di funzione, e l'ambito locale di "x" si applica per l'intera funzione, non solo dopo la posizione della linea "var x" nella funzione.

Ecco un caso più semplice di prova (testato tramite jsdb):

js>x = 0; 
0 
js>function foo(k) { x=k; } 
js>function bar(k) { var x=k; } 
js>function baz(k) { x=k; var x=2; } 
js>foo(1) 
js>x 
1 
js>bar(2) 
js>x 
1 
js>baz(3) 
js>x 
1 

noterete che l'unica funzione qui che colpisce il globale "x" è foo(). La funzione bar() riguarda ovviamente solo una x locale. Ma la funzione baz() riguarda anche solo la x locale. Si potrebbe pensare che l'assegnazione x=k; influenzi la x globale, poiché accade "prima" della successiva affermazione var x = 2; che sta chiaramente influenzando una variabile locale x. Ma sono abbastanza sicuro che se si esegue var x in una funzione, l'interprete lo vede e lo applica a tutti gli usi di x in tale ambito. La stessa situazione della tua.

5

La variabile x all'interno della funzione si crea immediatamente quando viene eseguita la funzione e non solo quando si raggiunge la linea con la variable statement:

Se l'istruzione variabile si verifica all'interno di un FunctionDeclaration, le variabili sono definito con scope locale della funzione in quella funzione [...]. Le variabili vengono create quando viene immesso l'ambito di esecuzione. [...] Le variabili vengono inizializzate su indefinite quando create. [...]

si può vedere che x è inizialmente undefined quando si aggiunge una chiamata log davanti al primo incarico:

function y(){ 
    log("0. " + x);//0. undefined 
    x = 1; 
    log("1. " + x);//1. 1 
    var x = 2; 
    log("2. " + x);//2. 2 
} 

Ciò significa che entrambe le assegnazioni all'interno della funzione si riferiscono alla x nel FUNCTION- ambito locale e non su x nell'ambito globale.

+0

+1 sì, e vedere la risposta di CMS anche perché utilizza la parola mancante "sollevamento". –

+0

+1 Grazie amico.Proprio quando penso di sapere cosa sta succedendo con JavaScript, qualcos'altro mi mette in crisi. Grazie per l'ottima risposta. – screenm0nkey