2014-07-01 17 views
10

Ho una pagina HTML con il seguente JavaScript allegato.Variabile JavaScript non definita vs non definita

alert(box); 
box = "Thinking outside the box"; 

Nella console ottengo "Uncaught ReferenceError: casella non è definito"

quando cambio a:

alert(box); 
var box = "Thinking outside the box"; 

L'allerta viene chiamato e mostra indefinito. Devo essere in grado di spiegarlo, ho una vaga idea del perché questo accada. So che quando uso var, JavaScript sa che la variabile è presente prima che l'avviso venga eseguito, ma non ha necessariamente assegnato un valore ad esso ?? Sono lontano qui? Hai bisogno di aiuto per capire questo.

+4

leggere su "sollevamento" – elclanrs

+0

scatola chiamata, prima di aver definito scatola, che non esiste, esiste solo quando si definisce, se 'si' ha un valore oppure no. – saj

+0

La tua comprensione è praticamente lì :) –

risposta

9

Quando si definisce una variabile con var, la dichiarazione della variabile viene "issata" nella parte superiore dell'ambito e pertanto la variabile viene definita per l'intero ambito. L'inizializzazione della variabile (assegnando il suo valore iniziale) rimane nella stessa posizione nel codice.

Quindi, nel secondo esempio, quando si esegue alert(box), la variabile box è già stata dichiarata a causa dell'istruzione sollevata var. Il tuo secondo esempio:

alert(box); 
var box = "Thinking outside the box"; 

è sostanzialmente equivalente a questo (la dichiarazione della variabile box viene issata alla cima del campo di applicazione):

var box; 
alert(box); 
box = "Thinking outside the box"; 

Questo rende la variabile box dichiarato (anche se non inizializzato) prima dell'affermazione alert(box) e quindi si ottiene un risultato coerente con la variabile dichiarata, ma senza valore (i report alert()undefined, ovvero ciò che accade quando la variabile esiste, ma non è ancora inizializzata).

tuo primo esempio non usa var e quindi non v'è alcun modo di sollevamento nel punto in cui si fa alert(box), non v'è alcuna variabile a tutti di nome box e quindi si ottiene il uncaught reference error.

Ci sono molti, molti post qui su SO che descrivono i dettagli del sollevamento. Puoi visualizzarne un lungo elenco qui: https://stackoverflow.com/search?q=javascript+variable+hoisting dove troverai ulteriori spiegazioni sul sollevamento variabile.

Nota: le dichiarazioni di funzione vengono anche sollevate in modo che alcuni dei post che si trovano riguardino le dichiarazioni di funzione piuttosto che le dichiarazioni di variabili, sebbene il concetto sia praticamente lo stesso.

+0

Controllare questa risposta correttamente in 3 minuti. lol Grazie, apprezzo la spiegazione. –

+1

Immagino che il motivo per cui ho avuto tanta difficoltà a trovare un altro post sia perché non ho capito il termine sollevamento. Ora sto trovando molte domande. –

+2

@EricB - sì, a volte basta conoscere la parola di ricerca operativa. – jfriend00

2

Questo ha a che fare con il sollevamento variabile. Ciò significa che, le dichiarazioni delle variabili (e le dichiarazioni in generale) vengono elaborate prima dell'esecuzione di qualsiasi codice, dichiarando che una variabile in qualsiasi punto del codice equivale a dichiararla in alto. Questo significa anche che una variabile può sembrare essere usata prima che sia dichiarata.

Quando si esegue il seguente:

alert(box) 
var box = "Thinking outside the box" 

questo è implicitamente intesa come:

var box; 
alert(box); 
box = "Thinking outside the box" 

Nel primo caso, non hai dichiarazioni di variabili, e quindi non è issato, a quel point box is undefined

Perché ciò accade?

Come Stoyan Stefanov spiega nel suo libro "Patterns JavaScript", di sollevamento è il risultato dell'attuazione del interprete JavaScript:

For completeness, let’s mention that actually at the implementation level things are a little more complex. There are two stages of the code handling, where variables, function declarations, and formal parameters are created at the first stage, which is the stage of parsing and entering the context. In the second stage, the stage of runtime code execution, function expressions and unqualified identifiers (undeclared variables) are created. But for practical purposes, we can adopt the concept of hoisting, which is actually not defined by ECMAScript standard but is commonly used to describe the behaviour.

- Stoyan Stefanov, "JavaScript Patterns"

Come una lettura lato, che collega this articolo dal sicuro Pastore.

+0

Questa è un'altra fantastica risposta e voglio ringraziarvi per averci dedicato del tempo e fare riferimento a questo grande libro. Ho sentito parlare del libro JavaScript Pattern di Stoyan ed è sul mio radar mentre imparo di più su JavaScript. Grazie per la risposta, ho già contrassegnato il james come corretto, ma mi limiterò alla tua risposta e ancora grazie per questo! –