Temporal Dead Zone en JavaScript: let, const y class | Nicolás Garzón
La Temporal Dead Zone , o TDZ, es el periodo entre el comienzo de un scope y el momento en que un binding léxico queda inicializado.
JavaScript
Copiar console. log ( value) ;
const value = 10 ; La TDZ evita que el código utilice una variable antes de que su declaración haya establecido un valor coherente.
JavaScript
Copiar const tax = subtotal * taxRate;
const taxRate = 0.19 ; Sin el error, taxRate podría leerse en un estado incompleto y producir resultados difíciles de detectar.
La TDZ convierte ese problema en un fallo inmediato y visible.
Para un binding de bloque, la TDZ comienza al entrar en el bloque y termina cuando la ejecución alcanza su declaración.
JavaScript
Copiar {
const subtotal = 100 ;
const price = 50 ;
console. log ( price) ;
} La palabra “temporal” se refiere al orden de ejecución dentro del scope.
let no exige un valor explícito, pero se inicializa cuando la ejecución alcanza la declaración.
JavaScript
Copiar console. log ( count) ;
let count;
console. log ( count) ; Antes de let count, está en TDZ. Después de la declaración, existe con valor undefined.
JavaScript
Copiar const value; const debe recibir un valor en la misma declaración porque después no puede reasignarse.
JavaScript
Copiar const value = 10 ; Esto no vuelve inmutable al valor; solo impide reasignar el binding.
JavaScript
Copiar const product = new Product ( ) ;
class Product { } La clase no puede utilizarse antes de su declaración.
typeof normalmente permite preguntar por un nombre inexistente sin lanzar error.
JavaScript
Copiar typeof missingValue; Pero falla cuando el nombre pertenece al scope y está en TDZ.
JavaScript
Copiar typeof value;
const value = 10 ; La diferencia es importante:
missingValue no tiene binding resoluble.
value sí tiene binding, pero todavía está sin inicializar.
JavaScript
Copiar const status = "outside" ;
{
console. log ( status) ;
const status = "inside" ;
} El binding local status oculta al exterior durante todo el bloque, incluso antes de su declaración.
JavaScript no “salta” hacia el binding exterior mientras el local está en TDZ.
JavaScript
Copiar function example ( condition ) {
if ( condition) {
console. log ( value) ;
}
const value = 10 ;
}
example(true) produce ReferenceError.
example(false) no intenta acceder a value antes de inicializarlo y termina normalmente.
La TDZ existe durante ese periodo, pero solo produce error cuando el código intenta acceder al binding.
Los parámetros por defecto se evalúan de izquierda a derecha.
JavaScript
Copiar function example ( first = second, second = 10 ) {
return first + second;
}
example ( ) ; Cuando se evalúa first = second, el parámetro second todavía no fue inicializado.
La dirección contraria sí funciona:
JavaScript
Copiar function example ( first = 10 , second = first ) {
return first + second;
}
example ( ) ; Este es un caso menos frecuente, pero demuestra que la TDZ también aparece en entornos de parámetros.
let crea bindings de bloque y, en ciertos bucles, un binding nuevo por iteración.
JavaScript
Copiar for ( let index = 0 ; index < 3 ; index++ ) {
} Esto será especialmente importante al estudiar closures y callbacks dentro de bucles.
JavaScript
Copiar const taxRate = 0.19 ;
const tax = subtotal * taxRate; JavaScript
Copiar const subtotal = calculateSubtotal ( items) ;
const taxRate = getTaxRate ( country) ;
const total = subtotal + subtotal * taxRate; JavaScript
Copiar const value = 10 ;
{
console. log ( value) ;
const localValue = 20 ;
} Aunque una declaración de función puede llamarse antes, mantener un orden claro reduce la carga mental.
La Temporal Dead Zone es un estado semántico del binding.
No significa que exista un área especial de memoria llamada TDZ. Significa que las operaciones de lectura o escritura sobre ese binding están prohibidas hasta su inicialización.
Creer que let y const no existen antes de su declaración.
Pensar que deberían devolver undefined como var.
Usar typeof esperando evitar cualquier ReferenceError.
Esperar que JavaScript encuentre un binding exterior cuando el local está en TDZ.
Confundir declaración con inicialización.
Declarar dependencias después del código que las utiliza.
Pensar que la TDZ solo afecta a const.
Olvidar que las clases y ciertos parámetros también pueden estar en TDZ.
La TDZ comienza al entrar en el scope del binding.
Termina cuando la declaración inicializa ese binding.
Afecta a let, const, class y otros bindings léxicos.
let sin inicializador queda en undefined después de su declaración.
const necesita un inicializador.
typeof lanza ReferenceError sobre un binding en TDZ.
Un binding local en TDZ oculta a uno exterior con el mismo nombre.
La TDZ es un estado del binding, no una región física de memoria.
JavaScript
Copiar const message = "outside" ;
function showMessage ( ) {
console. log ( message) ;
let message = "inside" ;
}
showMessage ( ) ; Respuesta Se produce un ReferenceError.
El message local pertenece a todo el scope de la función y oculta al exterior, pero todavía está sin inicializar cuando se ejecuta el console.log.
Contextos de ejecución conecta los scopes preparados con lo que ocurre cada vez que el programa o una función comienza a ejecutarse.