¿Cuál es la zona muerta temporal?


150

He escuchado que el acceso lety los constvalores antes de que se inicialicen pueden causar algo ReferenceErrordebido a la llamada zona muerta temporal .

¿Cuál es la zona muerta temporal, cómo se relaciona con el alcance y la elevación, y en qué situaciones se encuentra?


66
posible duplicado de ¿Las variables declaradas con let o const no se izan en ES6? - aunque la pregunta no se centra en el TDZ, las respuestas son básicamente las mismas
Bergi

Respuestas:


201

lety consttienen dos grandes diferencias de var:

  1. Tienen un alcance de bloque .
  2. Acceder a un varantes de que se declare tiene el resultado undefined; el acceso a una leto constantes de que sea declarada lanza ReferenceError:

console.log(aVar); // undefined
console.log(aLet); // causes ReferenceError: aLet is not defined
var aVar = 1;
let aLet = 2;

A partir de estos ejemplos, parece que las letdeclaraciones (y const, que funcionan de la misma manera) no se pueden izar , ya queaLet que no parece existir antes de que se le asigne un valor.

Sin embargo, ese no es el caso, lety const se izan (como var, classy function), pero hay un período entre el ingreso al alcance y la declaración donde no se puede acceder. Este período es la zona muerta temporal (TDZ) .

El TDZ finaliza cuando aLetse declara , en lugar de asignarse :

//console.log(aLet)  // would throw ReferenceError

let aLet;
console.log(aLet); // undefined
aLet = 10;
console.log(aLet); // 10

Este ejemplo muestra que letse iza:

let x = 'outer value';
(function() {
  // start TDZ for x
  console.log(x);
  let x = 'inner value'; // declaration ends TDZ for x
}());

Crédito: Temporal Dead Zone (TDZ) desmitificado

Acceder xen el ámbito interno todavía causa a ReferenceError. Si letno se izara, se registraría outer value.

El TDZ es bueno porque ayuda a resaltar errores: el acceso a un valor antes de que se haya declarado rara vez es intencional.

La TDZ también se aplica a los argumentos de función predeterminados. Los argumentos se evalúan de izquierda a derecha, y cada argumento está en la TDZ hasta que se asigna:

// b is in TDZ until its value is assigned
function testDefaults(a=b, b) { }
testDefaults(undefined, 1); // throws ReferenceError because the evaluation of a reads b before it has been evaluated.

El TDZ no está habilitado por defecto en el transpilador babel.js. Active el modo "alto cumplimiento" para usarlo en REPL . Proporcione la es6.spec.blockScopingbandera para usarla con la CLI o como biblioteca.

Lecturas recomendadas adicionales: TDZ desmitificado y ES6 Let, Const y la "Temporal Dead Zone" (TDZ) en profundidad .



@zeroflagL buen enlace, gracias. También dice: "foo no está declarado, no está inicializado", ese lenguaje sería útil para aclarar / corregir en la respuesta anterior. let fooen un bloque hace que se levante y se declare en la parte superior de ese bloque. La línea de let foohace que se inicialice. Y foo = xyzhace que se le asigne un valor.
AJP

2
¡Creo que esta es una gran publicación! Sin embargo, ¿tenía la impresión de que 'let' no estaba sujeto a izado? Encontré esto en los documentos de Mozilla: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… No estoy tratando de ser un cascarrabias, solo tenía curiosidad y estaba abierto a aclaraciones.
Dmarges

1
@jeows La página MDN todavía dice que no están izados. Debería intentar editar eso, si está realmente seguro de lo que está diciendo. Creo que debería publicar una pregunta al respecto.
doubleOrt

1
@joews IMO, podría decir que están izados pero no se puede acceder a ellos antes de que se llegue a su declaración debido a la TDZ, o podría decir que no están izados pero la TDZ hará que cualquier referencia a ellos arroje un error. Prácticamente, ambas afirmaciones son igualmente verdaderas. Excepto, creo, que está utilizando el término "elevación" en un sentido abstracto, como en "elevación = cuando el motor es consciente de la existencia de esa variable". Es esa la razón de ? Además, ¿qué dicen las especificaciones al respecto?
doubleOrt

7

Izado:
let , const, varson todos procesos izada a conseguir.
(lo que significa que suben y declaran en la parte superior del alcance).

Inicialización

  • varpasar también por el proceso inicial y obtener el valor inicial de undefined.
  • mientras let, constno se lanzó el proceso inicial, por lo que sus valores aún son inaccesibles, aunque ya lo declararon. en qué los colocastemporal dead zone

Entonces en breve:

proceso de elevación: var, let, const
Proceso de inicialización: var


0

En el caso de las variables let y const, Básicamente, Temporal Dead Zone es una zona

"antes de que se declare tu variable",

es decir, donde no puede acceder al valor de estas variables, arrojará un error.

ex.

let sum = a + 5;        //---------
//some other code       //         | ------>  this is TDZ for variable a
                        //         |
console.log(sum)        //---------
let a = 5;

el código anterior da un error

el mismo código no dará un error cuando usamos var para la variable 'a',

ex.

var sum = a;                            
console.log(sum)     //prints undefined
var a = 5;

el registro de la consola produce "NaN" en el segundo ejemplo (el resultado de agregar undefinedy 5). La declaración de var aes izada, el código de inicialización establecido aen 5 no lo es.
traktor53

sí, correcto, a se iza sin ninguna inicialización. Entonces a será indefinido.
niranjan harpale

El primer ejemplo citado no es correcto, corríjalo o elimínelo.
Web de Spidi el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.