Variables: Diferencias entre var, let y const
JavaScript ha evolucionado significativamente a lo largo de los años. Una de las mejoras más importantes fue la introducción de let
y const
para declarar variables, ofreciendo alternativas más seguras y predecibles a la forma original, var
.
En JavaScript existen tres formas principales de declarar variables: var
, let
y const
. Cada una tiene características específicas que las hacen adecuadas para diferentes situaciones. Comprender las diferencias entre ellas es importante para escribir código predecible y evitar errores comunes.
La Declaración Original y sus Peculiaridades: var
var
fue la única manera de declarar variables en JavaScript hasta la introducción de ES6. Aunque sigue siendo válida, esta presenta varias peculiaridades que pueden llevar a errores difíciles de rastrear. Veamos las principales:
1. Ámbito de Función (Function Scope)
Una variable declarada con var
es accesible en toda la función donde se define, sin importar si está dentro de un bucle o un condicional. “No respeta” los bloques {}.
function checkScope() {
for (var i = 0; i < 3; i++) {
console.log("Dentro del bucle:", i); // Funciona: 0, 1, 2
}
// ¡Sorpresa! 'i' se ha "fugado" del bucle y sigue siendo accesible aquí.
console.log("Fuera del bucle:", i); // Muestra 3
}
checkScope();
Este comportamiento, donde la variable “se fuga” de su bloque, puede causar sobrescrituras no deseadas en programas complejos.
2. Hoisting (Elevación)
Las declaraciones con var son “elevadas” al inicio de su función. Esto significa que puedes usar una variable antes de declararla en el código, y su valor será undefined en lugar de un error.
console.log(greeting); // Muestra: undefined
var greeting = "Hola";
console.log(greeting); // Muestra: "Hola"
Este “fallo silencioso” puede ocultar errores, ya que el código no se detiene donde debería.
3. Permite la Redeclaración
Puedes declarar la misma variable con var múltiples veces en el mismo ámbito sin que se produzca un error.
var user = "Ana";
console.log(user); // "Ana"
// ... mucho código después ...
// Esto es válido, pero puede sobrescribir una variable importante por accidente.
var user = "Carlos";
console.log(user); // "Carlos"
4. Problema de la Creación de Propiedades Globales
Las variables globales definidas con var
se agregan al objeto global como propiedades adicionales. Esto puede aumentar las posibilidades de conflictos con otras bibliotecas o scripts que también utilizan el objeto global para sus propias variables.
En el navegador web, el objeto global es window, mientras que en Node.js es global.
La Alternativa Moderna con Ámbito de Bloque: let
let
es una mejora significativa introducida en ES6 para declarar variables de manera más segura. Su ámbito está limitado al bloque en el que se declara, lo que evita problemas comunes asociados con el uso de var
.
1. Ámbito de Bloque (Block Scope)
Una variable let
solo existe y es accesible dentro del bloque ({}
) en el que se declara. Esto incluye bucles for
, condicionales if
y cualquier par de llaves.
function checkBlockScope() {
for (let i = 0; i < 3; i++) {
console.log("Dentro del bucle:", i); // Funciona: 0, 1, 2
}
// ¡Correcto! 'i' no existe aquí fuera. Intentar acceder a ella causa un error.
console.log("Fuera del bucle:", i); // ReferenceError: i is not defined
}
checkBlockScope();
Este comportamiento es mucho más predecible y previene la “fuga” de variables.
2. Zona Muerta Temporal (Temporal Dead Zone – TDZ)
Aunque las declaraciones let también son “elevadas”, no se inicializan. Entran en una “Zona Muerta Temporal” desde el inicio del bloque hasta que la línea de declaración es alcanzada. Intentar acceder a la variable en esta zona produce un error claro.
Básicamente La zona muerta temporal es el período entre el inicio del bloque y la declaración de la variable let
, durante el cual no se puede acceder a la variable. Intentar hacerlo generará un ReferenceError
.
// 'message' está en la TDZ en esta línea.
// console.log(message); // ReferenceError: Cannot access 'message' before initialization
let message = "Hola, mundo moderno";
console.log(message); // "Hola, mundo moderno"
Este error es una ventaja: te informa inmediatamente de que estás usando una variable antes de tiempo.
3. No Permite la Redeclaración
No puedes volver a declarar la misma variable con let en el mismo ámbito. Esto te protege de errores accidentales.
let color = "azul";
let color = "rojo"; // SyntaxError: Identifier 'color' has already been declared
El Estándar para Referencias Inmutables: const
const
se comporta de manera muy similar a let
(tiene ámbito de bloque y TDZ), pero con una regla adicional muy importante: su valor no puede ser reasignado.
1. Prohibida la Reasignación
Una vez que a una constante se le asigna un valor, no puedes asignarle uno nuevo.
const appVersion = "1.0.0";
appVersion = "1.0.1"; // TypeError: Assignment to constant variable.
2. La “Excepción” Crucial: Mutabilidad en Objetos y Arrays
La inmutabilidad de const
se aplica a la referencia de la variable, no al contenido del valor si este es un objeto o un array. Esto significa que puedes modificar las propiedades de un objeto o los elementos de un array declarados con const
.
const userConfig = {
theme: "dark",
notifications: true
};
// VÁLIDO: Estamos modificando una propiedad DENTRO del objeto.
userConfig.theme = "light";
console.log(userConfig.theme); // "light"
// INVÁLIDO: Estamos intentando asignar la variable a un objeto COMPLETAMENTE NUEVO.
// userConfig = { theme: "light", notifications: false }; // TypeError
Esta es la razón por la que const
es la opción preferida para objetos y arrays, ya que protege la variable de ser reemplazada por completo, pero permite que su contenido evolucione.
3. Requiere Inicialización
Debes asignar un valor a una const
en el momento de su declaración.
const API_KEY; // SyntaxError: Missing initializer in const declaration
console.log(API_KEY);
Uso de variables: ¿Cuándo Usar Cada Una?
La estrategia moderna para elegir es simple y promueve un código más seguro:
- Usa const por defecto. Siempre que declares una variable, empieza con const. Esto te da la máxima seguridad y comunica que el valor no debería ser reasignado.
- Cambia a let solo si necesitas reasignar. Si te das cuenta de que el valor de la variable necesita cambiar (por ejemplo, un contador en un bucle o el estado actual de un componente), entonces, y solo entonces, cambia const por let.
- Evita var por completo. En el desarrollo de JavaScript moderno, no existen escenarios donde var sea preferible a let. Usar let y const te ayudará a evitar una categoría entera de errores.
Conclusión
Adoptar let y const no es solo una cuestión de estilo; es una práctica fundamental para escribir código JavaScript robusto, predecible y fácil de mantener. Al entender claramente sus diferencias, te posicionas para construir aplicaciones más fiables y alinear tu código con los estándares profesionales de hoy.
En el próximo artículo nos adentraremos en los tipos de datos en JavaScript, explorando cada uno en detalle.