Scope, hoisting y TDZ: por qué tu variable existe (o falla) en cada línea

Domina alcance léxico, elevación y zona temporal muerta para evitar ReferenceError, corregir sombras de variables y escribir funciones más predecibles.

Cuando aparece un `ReferenceError`, casi nunca es magia: suele ser un problema de scope o de orden de ejecución en tu código.

Esta lección te enseña a pensar como el motor de JavaScript: qué declara primero, qué inicializa después y qué puedes leer en cada bloque.

Entender `hoisting` y `TDZ` te evita bugs muy caros en formularios, módulos y callbacks asíncronos.

Además, te prepara para closures y diseño de funciones limpias en lecciones siguientes.

  • Tres ideas conectadas que explican por qué una variable funciona en un sitio y rompe en otro.
  • `Scope` define dónde puedes acceder a una variable. `Hoisting` explica qué declaraciones se procesan antes de ejecutar línea a línea. `TDZ` marca el tramo donde `let/const` existen pero aún no pueden usarse.
  • Si entiendes esta triada, tus errores dejan de ser aleatorios y se vuelven totalmente rastreables.
  • El contexto donde declaras una variable determina quién puede verla.
  • JavaScript usa alcance léxico: no importa desde dónde llames una función, importa dónde fue definida.

Mapa conceptual: scope, hoisting y TDZ

Tres ideas conectadas que explican por qué una variable funciona en un sitio y rompe en otro.

`Scope` define dónde puedes acceder a una variable. `Hoisting` explica qué declaraciones se procesan antes de ejecutar línea a línea. `TDZ` marca el tramo donde `let/const` existen pero aún no pueden usarse.

Si entiendes esta triada, tus errores dejan de ser aleatorios y se vuelven totalmente rastreables.

Scope léxico: el bloque manda

El contexto donde declaras una variable determina quién puede verla.

JavaScript usa alcance léxico: no importa desde dónde llames una función, importa dónde fue definida.

En código real, esta idea es crucial al trabajar con handlers de eventos y funciones internas.

Hoisting real sin mitos

No todo se eleva igual: declara una cosa, inicializa otra.

Las declaraciones `function` quedan disponibles antes de su línea. Con `var`, la declaración se eleva pero su valor inicial es `undefined` hasta asignación. Con `let/const`, hay hoisting, pero no acceso antes de inicializar (TDZ).

Por eso conviene declarar variables al inicio del bloque y funciones auxiliares antes de su primer uso, para mejorar legibilidad del flujo.

TDZ (Temporal Dead Zone): error útil, no enemigo

La TDZ te protege de usar variables antes de tiempo.

La TDZ empieza al entrar en el bloque y termina en la línea donde inicializas `let/const`.

Ese `ReferenceError` temprano evita bugs silenciosos que antes con `var` podían pasar desapercibidos durante mucho tiempo.

  • Si ves TDZ, revisa orden de declaración e inicialización.
  • No mezcles definición y uso en bloques largos sin estructura.
  • Prefiere funciones pequeñas para reducir contexto mental.

Shadowing y nombres: evita confusión accidental

Puedes redeclarar en bloque interno, pero hazlo con criterio.

Shadowing ocurre cuando una variable interna tapa otra externa con el mismo nombre. No siempre es error, pero sí una fuente frecuente de confusión.

En equipos, renombrar de forma semántica (`precioBase`, `precioConIva`) suele ser mejor que reutilizar `precio` en todos lados.

JavaScript
11

Scope, hoisting y TDZ: por qué tu variable existe (o falla) en cada línea

Domina alcance léxico, elevación y zona temporal muerta para evitar ReferenceError, corregir sombras de variables y escribir funciones más predecibles.

Código del tema: let · const · var · function

📘 Teoría

Mapa conceptual: scope, hoisting y TDZ

Tres ideas conectadas que explican por qué una variable funciona en un sitio y rompe en otro.

`Scope` define dónde puedes acceder a una variable. `Hoisting` explica qué declaraciones se procesan antes de ejecutar línea a línea. `TDZ` marca el tramo donde `let/const` existen pero aún no pueden usarse.

Si entiendes esta triada, tus errores dejan de ser aleatorios y se vuelven totalmente rastreables.

1

Global scope

Visible desde todo el archivo/módulo.

  • Útil para configuración general
  • Peligroso si abusas: acopla demasiado
2

Function scope

Variables vivas solo dentro de la función.

  • Encapsula lógica
  • Reduce efectos colaterales
3

Block scope

Con `let/const`, vive en `{}`.

  • if/for/while crean bloque
  • Evita fugas de variables
4

TDZ

Zona temporal muerta de `let/const`.

  • Existe antes de inicializar
  • Leer antes => `ReferenceError`

Scope léxico: el bloque manda

El contexto donde declaras una variable determina quién puede verla.

1

JavaScript usa alcance léxico: no importa desde dónde llames una función, importa dónde fue definida.

2

En código real, esta idea es crucial al trabajar con handlers de eventos y funciones internas.

Block scope con let
const app = 'dashboard';

if (app === 'dashboard') {
  let mensaje = 'Vista interna';
  console.log(mensaje); // OK
}

// console.log(mensaje); // ReferenceError

Hoisting real sin mitos

No todo se eleva igual: declara una cosa, inicializa otra.

Las declaraciones `function` quedan disponibles antes de su línea. Con `var`, la declaración se eleva pero su valor inicial es `undefined` hasta asignación. Con `let/const`, hay hoisting, pero no acceso antes de inicializar (TDZ).

Por eso conviene declarar variables al inicio del bloque y funciones auxiliares antes de su primer uso, para mejorar legibilidad del flujo.

Comparativa rápida
console.log(typeof helper); // function
helper();

function helper() {
  console.log('Función disponible');
}

console.log(valorVar); // undefined
var valorVar = 10;

// console.log(valorLet); // ReferenceError (TDZ)
let valorLet = 20;

TDZ (Temporal Dead Zone): error útil, no enemigo

La TDZ te protege de usar variables antes de tiempo.

La TDZ empieza al entrar en el bloque y termina en la línea donde inicializas `let/const`.

Ese `ReferenceError` temprano evita bugs silenciosos que antes con `var` podían pasar desapercibidos durante mucho tiempo.

  • Si ves TDZ, revisa orden de declaración e inicialización.
  • No mezcles definición y uso en bloques largos sin estructura.
  • Prefiere funciones pequeñas para reducir contexto mental.
Ejemplo típico TDZ
function calcular() {
  // console.log(total); // TDZ
  const total = 100;
  return total;
}

console.log(calcular());

Shadowing y nombres: evita confusión accidental

Puedes redeclarar en bloque interno, pero hazlo con criterio.

1

Shadowing ocurre cuando una variable interna tapa otra externa con el mismo nombre. No siempre es error, pero sí una fuente frecuente de confusión.

2

En equipos, renombrar de forma semántica (`precioBase`, `precioConIva`) suele ser mejor que reutilizar `precio` en todos lados.

Shadowing controlado
const rol = 'usuario';

function revisarPermiso() {
  const rol = 'admin';
  console.log('interno:', rol);
}

revisarPermiso();
console.log('externo:', rol);

🧭 Visuales clave

Scope y ámbito

Refuerza cómo se resuelven variables según el contexto de ejecución.

Esquema de alcance global, de bloque y de función

🧪 Aprende probando

Ejemplo Ejemplo guiado: scope en validación de acceso Observa qué variables viven dentro del bloque y cuáles quedan accesibles fuera.
Ejemplo Ejemplo guiado: hoisting en función vs var Compara comportamiento para entender por qué no todo se eleva igual.
Ejemplo Demo interactiva: visor de scope y TDZ Selecciona un caso y revisa en preview + consola el resultado de cada patrón de alcance.

🏁 Retos

Reto Reto 1: corrige TDZ por orden de declaración Reordena y ajusta el código para evitar uso de `let` antes de inicializar.
Reto Reto 2: evita shadowing confuso Refactoriza nombres para que variable externa e interna no se pisen semánticamente.

¿Qué es esto?

Soy Cristian Eslava y a veces hago webs para procrastinar yo y vosotros 😉.

Esta la hice en febrero de 2026 para facilitar el aprendizaje de mis alumnxs. Aprender desarrollo web practicando. La idea es que crezca semanalmente con nuevos temas, tests y retos.

Inspirado en MDN, en W3Schools, en Codepen, en el crack de Manz y en mil sitios de documentación sobre desarrollo web. Quería aportar además de bloques teóricos con ejemplos, la gamificación de los retos y el sistema de test que ya tenía en culTest .

Si te gustó, si no te gustó, si quieres saludarme, o invitarme a 🍻 no dudes en escribirme en cristianeslava@gmail.com .