Hoisting en JavaScript
Entiende el mecanismo de elevación (hoisting), sus implicaciones en var, let, const y funciones, y descubre cómo escribir código predecible y libre de errores.
¿Qué es el hoisting?
En JavaScript, hoisting (elevación) es el proceso interno mediante el cual los declaradores de variables y funciones son movidos al top (cima) de su contexto de ejecución antes de que el código sea evaluado. No se mueve el valor, solo la declaración.
Esto significa que puedes referirte a una variable o función antes de haberla escrito en el archivo, pero el comportamiento varía según el tipo de declaración.
Hoisting de var vs let/const
var
- La declaración se eleva al inicio del function scope o global scope.
- Se inicializa con
undefineddurante la fase de creación. - Puede ser redeclarada dentro del mismo scope sin error.
console.log(a); // undefined (no error)
var a = 10;
console.log(a); // 10
let / const
- La declaración también se eleva, pero queda en la Temporal Dead Zone (TDZ) hasta que se ejecuta la línea de inicialización.
- Acceder antes de la inicialización lanza
ReferenceError. constrequiere inicialización inmediata y es inmutable (no redeclarable).
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 20;
console.log(b); // 20
console.log(c); // ReferenceError
const c = 30; // obligatorio inicializar
Hoisting de funciones
Existen dos formas de declarar funciones:
Declaración de función (Function Declaration)
- Se eleva completa: tanto la firma como el cuerpo.
- Disponible en cualquier punto del scope.
saludar(); // "Hola"
function saludar(){
console.log('Hola');
}
Expresión de función (Function Expression)
- Solo la variable se eleva (como
var), el valor (la función) no. - Acceder antes de la asignación produce
TypeError(undefined no es una función).
intentar(); // TypeError: intentar is not a function
var intentar = function(){
console.log('Intento');
};
Comparativa rápida
| Aspecto | var |
let / const |
Function Declaration | Function Expression |
|---|---|---|---|---|
| Elevación | Sí, como undefined |
Sí, pero en TDZ | Sí, cuerpo completo | Sí, solo la variable |
| Scope | Funcional / Global | Bloque | Funcional / Global | Bloque (según la variable) |
| Redeclarable | Sí | No | No (en mismo scope) | No (por la variable) |
| Inicialización automática | >Sí (undefined) | No (TDZ) | Sí (función completa) | No (undefined) |
Buenas prácticas para evitar sorpresas de hoisting
- Usa siempre
letoconst. Elimina la ambigüedad delvary protege contra redeclaraciones accidentales. - Declara funciones antes de usarlas cuando utilices expresiones de función o arrow functions.
- Activa
eslintcon la reglano-use-before-definepara detectar accesos prematuros. - Utiliza módulos ES6 (
import/export) que se ejecutan en modo estricto y evitan la mayoría de los problemas de hoisting. - Documenta el orden de inicialización en archivos grandes: agrupa constantes, luego variables, y por último funciones auxiliares.
Depuración y troubleshooting
Cuando encuentres ReferenceError: Cannot access 'X' before initialization o TypeError: X is not a function, sigue estos pasos:
- Revisa la posición de la declaración respecto al uso.
- Comprueba si la variable está declarada con
var(puede serundefined). - Usa
console.logantes de la línea problemática para ver cuál es el valor real. - En entornos Node, ejecuta con la bandera
--trace-uncaughtpara obtener stack traces más claros.
Impacto en rendimiento y escalabilidad
El proceso de hoisting es parte del phase de creación del Execution Context y ocurre una sola vez por contexto. En la práctica, su coste es insignificante comparado con la lógica de negocio. Sin embargo, un uso indiscriminado de var en funciones muy largas puede generar contaminación del scope y dificultar la optimización de motores JIT.
Recomendación: mantén los scopes pequeños, usa let/const y declara funciones con function si necesitas que estén disponibles en todo el módulo; de lo contrario, prefiere arrow functions asignadas a constantes.
Hoisting en JavaScript: Conceptos, Ejemplos y Buenas Prácticas