@thefourtheye tiene razón al decir que no se puede acceder a estas variables antes de declararlas. Sin embargo, es un poco más complicado que eso.
¿Las variables se declaran con let
o const
no izadas? ¿Qué está pasando aquí realmente?
Todas las declaraciones ( var
, let
, const
, function
, function*
, class
) se "izan" en JavaScript. Esto significa que si se declara un nombre en un ámbito, en ese ámbito el identificador siempre hará referencia a esa variable en particular:
x = "global";
// function scope:
(function() {
x; // not "global"
var/let/… x;
}());
// block scope (not for `var`s):
{
x; // not "global"
let/const/… x;
}
Esto es cierto tanto para la función como para los ámbitos de bloque 1 .
La diferencia entre var
/ function
/ function*
declaraciones y let
/ const
/ class
declaraciones es la inicialización .
Los primeros se inicializan con undefined
o la función (generador) justo cuando el enlace se crea en la parte superior del alcance. Sin embargo, las variables declaradas léxicamente permanecen sin inicializar . Esto significa que se ReferenceError
produce una excepción cuando intenta acceder a ella. Solo se inicializará cuando se evalúe la instrucción let
/ const
/ class
, todo lo anterior (arriba) que se denomina zona muerta temporal .
x = y = "global";
(function() {
x; // undefined
y; // Reference error: y is not defined
var x = "local";
let y = "local";
}());
Observe que una let y;
instrucción inicializa la variable con undefined
like let y = undefined;
habría.
La zona muerta temporal no es una ubicación sintáctica, sino el tiempo entre la creación de la variable (alcance) y la inicialización. No es un error hacer referencia a la variable en el código sobre la declaración, siempre y cuando ese código no se ejecute (por ejemplo, un cuerpo de función o simplemente un código muerto), y arrojará una excepción si accede a la variable antes de la inicialización, incluso si el acceso el código está debajo de la declaración (por ejemplo, en una declaración de función izada que se llama demasiado pronto).
¿Hay alguna diferencia entre let
y const
en este asunto?
No, funcionan igual en lo que respecta a la elevación. La única diferencia entre ellos es que una const
hormiga debe ser y solo puede asignarse en la parte inicial de la declaración ( const one = 1;
tanto las const one;
reasignaciones como las posteriores one = 2
no son válidas).
1: las var
declaraciones siguen funcionando solo en el nivel de función, por supuesto
let foo = () => bar; let bar = 'bar'; foo();
ilustra que todas las declaraciones son efecto de elevación aún mejor, porque no es obvio debido a la zona muerta temporal.