2010-07-27 10 views
7

¿Puede alguien decirme por qué el último registro de 'x' es igual a 0 y no a 1. Pensé que porque está declarado fuera de una función tiene alcance global y luego en la función se establece su valor a 1 y ese valor se mantendría ya que es un global? Sé que el primer valor 'x' dentro de la función es global, ya que cualquier variable declarada sin la palabra clave var se convierte en una propiedad del objeto ventana. Muchas graciasY pensé que entendía 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 

Respuesta

6

La declaración var es objeto de izado, cuando se evalúa el código de lo que realmente se ve así:

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 

Justo antes y se ejecuta, un nuevo contexto de ejecución es de configuración, y el proceso Variable Instantiation toma lugar antes de la función se ejecuta.

Esa es una de las razones por las cuales JSLint recomienda solo una sentencia var por función, para parecerse a lo que realmente está sucediendo.

+0

Gracias hombre. Siempre puedo responderle por la respuesta. – screenm0nkey

+0

De nada, ¡estoy contento de ayudar! – CMS

1

I que, pero no puedo confirmar a través de la especificación ECMAScript, que la "x = var 2" línea se analizará en el momento de definición de función, y el alcance local de "x" se aplica a la totalidad función, no solo después de la posición de la línea "var x" en la función.

Aquí es un caso más simple prueba (probado a través de 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 

Se habrá dado cuenta de que la única función aquí mundial que afecta a la "x" es foo(). La función bar() obviamente afecta solo a una x local. Pero la función baz() también afecta solo a la x local. Usted pensaría que la asignación x=k; afectaría a la x global, ya que ocurre "antes" de la siguiente declaración var x = 2; que claramente afecta a una variable local x. Pero estoy bastante seguro de que si hace var x en una función, el intérprete lo ve y lo aplica a todos los usos de de ese alcance. La misma situación que la tuya.

5

La variable x dentro de la función se crea inmediatamente cuando se ejecuta la función y no sólo cuando se alcanza la línea con el variable statement:

Si la sentencia de variable se produce dentro de un FunctionDeclaration, las variables son definido con el alcance local de la función en esa función [...]. Las variables se crean cuando se ingresa el alcance de la ejecución. [...] Las variables se inicializan en undefined cuando se crean. [...]

Se puede ver que es x inicialmente undefined al agregar una llamada log delante de la primera asignación:

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

Eso significa que ambas asignaciones dentro de la función se refieren a x en el automático- alcance local y no a x en el alcance global.

+0

+1 sí, y vea la respuesta de CMS también porque usa la palabra que falta "elevación". –

+0

+1 Gracias hombre.Justo cuando creo que sé lo que está pasando con JavaScript, algo más me detiene. Gracias por una gran respuesta. – screenm0nkey