w3schools entre diferencias diferencia and javascript ecmascript-6 const let hoisting

javascript - entre - hoisting



¿Las variables declaradas con let o const no se izan en ES6? (4)

@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 declaradas con let o const no están elevadas? ¿Qué está pasando aquí realmente?

Todas las declaraciones ( var , let , const , function , function* , class ) se "izan" en JavaScript. Esto significa que si un nombre se declara 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 las declaraciones var / function / function* y let / const / class es la inicialización .
Los primeros se inicializan con undefined o la función (generador) justo cuando se crea el enlace en la parte superior del alcance. Sin embargo, las variables declaradas léxicamente permanecen sin inicializar . Esto significa que se produce una excepción ReferenceError cuando intenta acceder a ella. Solo se inicializará cuando se evalúe la declaración let / const / class , todo antes (arriba) que se llama zona muerta temporal .

x = y = "global"; (function() { x; // undefined y; // Reference error: y is not defined var x = "local"; let y = "local"; }());

Tenga en cuenta que a let y; La instrucción inicializa la variable con undefined como let y = undefined; tendrí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 encima de la declaración siempre que 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 debe ser y solo puede asignarse en la parte inicializadora de la declaración ( const one = 1; ambas const one; y las reasignaciones posteriores como one = 2 no son válidas).

1: las declaraciones var todavía funcionan solo en el nivel de función, por supuesto

He estado jugando con ES6 durante un tiempo y noté que mientras las variables declaradas con var se izan como se esperaba ...

console.log(typeof name); // undefined var name = "John";

... las variables declaradas con let o const parecen tener algunos problemas con la elevación:

console.log(typeof name); // ReferenceError let name = "John";

y

console.log(typeof name); // ReferenceError const name = "John";

¿Significa esto que las variables declaradas con let o const no se izan? ¿Qué está pasando aquí realmente? ¿Hay alguna diferencia entre let y const en este asunto?


Citando las especificaciones de ECMAScript 6 (ECMAScript 2015), la sección de declaraciones let y const ,

Las variables se crean cuando se crea una instancia de su entorno léxico que contiene, pero no se puede acceder de ninguna manera hasta que se evalúe el enlace léxico de la variable .

Entonces, para responder a su pregunta, sí, let y conteste pero no puede acceder a ellos antes de que se evalúe la declaración real en tiempo de ejecución.


De los documentos web de MDN:

En ECMAScript 2015, let y const se izan pero no se inicializan. Hacer referencia a la variable en el bloque antes de la declaración de la variable da como resultado un ReferenceError porque la variable está en una "zona muerta temporal" desde el inicio del bloque hasta que se procese la declaración.

console.log(x); // ReferenceError let x = 3;


ES6 presenta las variables Let que aparecen con el block level scoping . Hasta ES5 no teníamos el block level scoping , por lo que las variables que se declaran dentro de un bloque siempre se hoisted para el alcance del nivel de función.

Básicamente, Scope refiere a dónde están visibles las variables en su programa, lo que determina dónde se le permite usar las variables que ha declarado. En ES5 tenemos global scope,function scope and try/catch scope , con ES6 también obtenemos el alcance del nivel de bloque usando Let.

  • Cuando define una variable con la palabra clave var , se conoce toda la función desde el momento en que se define.
  • Cuando define una variable con una declaración let , solo se conoce en el bloque que está definido.

    function doSomething(arr){ //i is known here but undefined //j is not known here console.log(i); console.log(j); for(var i=0; i<arr.length; i++){ //i is known here } //i is known here //j is not known here console.log(i); console.log(j); for(let j=0; j<arr.length; j++){ //j is known here } //i is known here //j is not known here console.log(i); console.log(j); } doSomething(["Thalaivar", "Vinoth", "Kabali", "Dinesh"]);

Si ejecuta el código, podría ver que la variable j solo se conoce en el loop y no antes y después. Sin embargo, nuestra variable i es conocida en entire function desde el momento en que se define en adelante.

Hay otra gran ventaja con let, ya que crea un nuevo entorno léxico y también une un valor fresco en lugar de mantener una referencia antigua.

for(var i=1; i<6; i++){ setTimeout(function(){ console.log(i); },1000) } for(let i=1; i<6; i++){ setTimeout(function(){ console.log(i); },1000) }

El primer bucle for siempre imprime el último valor, con let crea un nuevo ámbito y enlaza valores nuevos imprimiéndonos 1, 2, 3, 4, 5 .

Llegando a constants , funciona básicamente como let , 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.

const foo = {}; foo.bar = 42; console.log(foo.bar); //works const name = [] name.push("Vinoth"); console.log(name); //works const age = 100; age = 20; //Throws Uncaught TypeError: Assignment to constant variable. console.log(age);

Si una constante se refiere a un object , siempre se referirá al object pero el object sí se puede cambiar (si es mutable). Si desea tener un object inmutable, puede usar Object.freeze([])