2012-11-29 10 views
6

Nel codice seguente:ridichiarare JavaScript variabile

var greeting = "hi"; 

function changeGreeting() { 
    if (greeting == "hi") { 
     var greeting = "hello"; 
    } 

    alert(greeting); 
} 

changeGreeting();​ 

... greeting non è definito. Tuttavia se mi tolgo la var e cambiare changeGreeting() a questo:

function changeGreeting() { 
    if (greeting == "hi") { 
     greeting = "hello"; 
    } 

    alert(greeting); 
} 

... ho "ciao" come previsto.

Non vorrei mai ridichiarare una variabile come questa nel mio codice, ma perché succede?

risposta

27

Le variabili JavaScript hanno scope di funzione. Pertanto, la presenza stessa di var greeting all'interno della funzione dichiarerà una variabile locale greeting, che sarà indefinita al momento della sua menzione nella condizione if: la variabile globale non sarà visibile all'interno della funzione, essendo oscurata da quella locale. Pertanto, il if non si verifica, l'assegnazione a hello non si verifica, la variabile non è ancora definita.

Nel secondo esempio, si sta utilizzando la variabile globale in tutto, non è oscurata da una variabile locale (perché, senza var greeting all'interno della funzione) e le cose funzionano come previsto.

+3

+1 Risposta ben formulata e chiara. – Aesthete

+0

+1 davvero per voi signore. –

+0

@bfavaretto: ho pensato che 'var greeting' fosse un errore, e si supponeva fosse la dichiarazione delle variabili globali' var currentSize' (che sarebbe stata oscurata nel primo esempio e utilizzata nel secondo). Altrimenti sarebbe del tutto irrilevante per l'esempio. – Amadan

-1

Nel tuo primo frammento di codice, stai controllando la variabile globale, che non esiste -> non passa se condizione.

Partenza questo su javascript scopi e come lavorare con le variabili Javascript garden - function scopes

+1

Il primo snippet è _non_ controllando una variabile globale, il corpo della funzione contiene una dichiarazione 'var' di quella stessa variabile, che viene issata in alto. Sta controllando un valore locale var currentLength; '<- variabile non definita che è GC dopo che la funzione restituisce –

+0

Ah, hai ragione. Ho completamente cancellato il sollevamento:/ – rdamborsky

6

E 'molto semplice: JS issare le dichiarazioni variabili alla parte superiore dell'ambito corrente, ma eventuali operazioni (tra cui le assegnazioni) non sono issato (all'interno dello stesso scopo, vedere la seconda spiegazione), naturalmente. Così il vostro frammento è tradotto per

(function() 
{ 
    var currentSize;//undefined 
    if (currentSize == 'hi')//always false 
    { 
     currentSize = 'hello';//assignment that will never be 
    } 
    alert(currentSize);//alerts undefined, of course 
}()); 

tralasciando il var, procede alla scansione portata (il controllo per la variabile viene dichiarata nello scope globale). Purtroppo, nel fare ciò, il contesto del primo utilizzo della var viene perso (all'interno di una diramazione) e anche l'assegnazione viene sollevata. Un implicito globale è tradotto in :
Grazie a dio questo non è vero. Ho pensato che lo fosse, perché ho verificato un paio di cose nella console che sembravano confermarlo. In questo caso @amadan ha ragione: stai utilizzando la variabile globale (chiamata greeting nello snippet per errore quando l'ho pubblicata). Lascerò il codice qui sotto (corretto) per mostrare cosa sono effettivamente le implicite globals, sperando che aiuti qualcuno a capire a fondo gli scope/scope-scanning in JS.

var currentSize = 'hello'; 
//well, actually implied globals can be deleted, so it's more like 
Object.defineProperty(this,'currentSize',{value:undefined, 
              writable:true, 
              enumerable:true, 
              configurable:true}); 
(function() 
{ 
    if (currentSize == 'hi')//always false 
    {//this still doesn't get executed 
     currentSize = 'hello';//assignment that will never be 
    } 
    alert(currentSize);//alerts undefined 
}()); 
+0

Una risposta ben spiegata sull'ambito variabile Ho imparato molto da esso per correggere il mio concetto sull'ambito variabile in JS –

Problemi correlati