Este fenómeno se conoce como: Elevación variable de JavaScript .
En ningún momento accede a la variable global en su función; solo está accediendo a la value
variable local .
Su código es equivalente a lo siguiente:
var value = 10;
function test() {
var value;
console.log(value);
value = 20;
console.log(value);
}
test();
¿Todavía te sorprende que te estés recibiendo undefined
?
Explicación:
Esto es algo con lo que todos los programadores de JavaScript se topan tarde o temprano. En pocas palabras, lo variables que se declaran siempre está izada a la parte superior de su clausura local. Entonces, aunque declaró su variable después de la primera console.log
llamada, todavía se considera como si la hubiera declarado antes.
Sin embargo, solo se iza la parte de la declaración; la asignación, por otro lado, no lo es.
Entonces, cuando llamó por primera vez console.log(value)
, estaba haciendo referencia a su variable declarada localmente, que aún no tiene nada asignado; por lo tanto undefined
.
Aquí hay otro ejemplo :
var test = 'start';
function end() {
test = 'end';
var test = 'local';
}
end();
alert(test);
¿Qué crees que alertará esto? No, no se limite a seguir leyendo, piénselo. ¿Cuál es el valor de test
?
Si dijiste algo más que start
, estabas equivocado. El código anterior es equivalente a esto:
var test = 'start';
function end() {
var test;
test = 'end';
test = 'local';
}
end();
alert(test);
para que la variable global nunca se vea afectada.
Como se puede ver, no importa donde usted pone su declaración de variables, siempre es izada a la parte superior de su clausura local.
Nota al margen:
Esto también se aplica a las funciones.
Considere este fragmento de código :
test("Won't work!");
test = function(text) { alert(text); }
que le dará un error de referencia:
Error de referencia no detectado: la prueba no está definida
Esto desconcierta a muchos desarrolladores, ya que este código funciona bien:
test("Works!");
function test(text) { alert(text); }
La razón de esto, como se indicó, es que la parte de asignación no está izada. Entonces, en el primer ejemplo, cuando test("Won't work!")
se ejecutó, la test
variable ya ha sido declarada, pero aún no se le ha asignado la función.
En el segundo ejemplo, no usamos la asignación de variables. Más bien, estamos usando la sintaxis de declaración de función adecuada, lo que hace que la función sea completamente mejorada.
Ben Cherry ha escrito un artículo excelente sobre esto, apropiadamente titulado Alcance y elevación de JavaScript .
Léelo. Le dará la imagen completa con todos los detalles.