@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.const
comolet
es un defecto de diseño. Dentro de un alcance,const
debería haber sido hecho para ser izado e inicializado justo a tiempo cuando se accede a él. Realmente, deberían tener unaconst
, unalet
, y otra palabra clave que cree una variable que funcione como un "solo lectura"let
.Citando la sección de especificaciones
let
yconst
declaraciones de ECMAScript 6 (ECMAScript 2015) ,Entonces, para responder a su pregunta, sí,
let
yconst
izar pero no puede acceder a ellos antes de que se evalúe la declaración real en tiempo de ejecución.fuente
ES6
introduceLet
variables que surgenblock level scoping
. HastaES5
que no lo teníamosblock level scoping
, entonces las variables que se declaran dentro de un bloque siempre tienen unhoisted
alcance de nivel funcional.Básicamente se
Scope
refiere a en qué parte de su programa están visibles sus variables, lo que determina dónde puede usar las variables que ha declarado. EnES5
tenemosglobal scope,function scope and try/catch scope
, conES6
también obtenemos el alcance del nivel de bloque mediante el uso de Let.var
palabra clave, se conoce toda la función desde el momento en que se define.Cuando define una variable con una
let
declaración, solo se conoce en el bloque que está definido.Si ejecuta el código, podría ver que la variable
j
solo se conoce enloop
y no antes y después. Sin embargo, nuestra variablei
se conoceentire function
desde el momento en que se define en adelante.Existe otra gran ventaja al usar let, ya que crea un nuevo entorno léxico y también une un valor fresco en lugar de mantener una referencia antigua.
El primer
for
ciclo siempre imprime el último valor, conlet
él crea un nuevo alcance y enlaza valores nuevos imprimiéndonos1, 2, 3, 4, 5
.En resumen
constants
, funciona básicamente comolet
, la única diferencia es que su valor no se puede cambiar. En constantes, la mutación está permitida pero la reasignación no está permitida.Si una constante se refiere a una
object
, siempre se referirá a laobject
pero laobject
misma se puede cambiar (si es mutable). Si te gusta tener un inmutableobject
, puedes usarObject.freeze([])
fuente
De los documentos web de MDN:
En ECMAScript 2015,
let
yconst
se izan pero no se inicializan. Hacer referencia a la variable en el bloque antes de que la declaración de variable resulte en unReferenceError
porque la variable está en una "zona muerta temporal" desde el comienzo del bloque hasta que se procese la declaración.fuente
en es6 cuando usamos let o const tenemos que declarar la variable antes de usarlos. p.ej. 1 -
p.ej. 2-
fuente