Variables
En JavaScript, las variables son fundamentales para almacenar y manipular datos. Sin embargo, no todas las variables se comportan igual, ya que su visibilidad y alcance (conocido como scope) dependen del contexto en el que se definen. En este artículo, veremos los tres tipos principales de variables en JavaScript y cómo su scope afecta su uso.
JavaScript ofrece tres formas de declarar variables: var, let y const.
var
El tipo de declaración más antiguo, usado antes de la introducción de ES6. Tiene un alcance de función o global, lo que significa que una variable declarada con var dentro de una función solo es accesible dentro de esa función. Si se declara fuera de cualquier función, es accesible globalmente en todo el programa.
function ejemploVar() {
var mensaje = "Hola, soy una variable con var";
console.log(mensaje); // "Hola, soy una variable con var"
}
console.log(mensaje); // ReferenceError: mensaje is not defined
En este ejemplo, la variable mensaje no es accesible fuera de la función, ya que var tiene un scope limitado a la función en la que se declara.
Las variables declaradas con var son "elevadas" al principio de su scope, lo que permite usarlas antes de su declaración, aunque el valor será undefined hasta que se inicialicen. Este proceso se conoce como hoisting.
console.log(mensaje); // undefined
var mensaje = "Hola";
let
Introducido en ES6, let ofrece un scope de bloque, es decir, las variables declaradas con let solo son accesibles dentro del bloque ({}) en el que se declaran, ya sea en una función, un bucle, o una condición.
if (true) {
let saludo = "Hola desde let";
console.log(saludo); // "Hola desde let"
}
console.log(saludo); // ReferenceError: saludo is not defined
Aquí, saludo es accesible solo dentro del bloque if. Fuera de ese bloque, la variable no existe.
const
También introducido en ES6, const tiene el mismo scope de bloque que let, pero con la restricción de que su valor no puede cambiar después de ser asignado. Es útil para declarar constantes.
const PI = 3.14;
console.log(PI); // 3.14
PI = 3.1416; // Error: Assignment to constant variable.
Aunque no puedes reasignar una variable const, ten en cuenta que si se trata de un objeto o un array, sus propiedades o elementos pueden modificarse.
const persona = { nombre: "Juan" };
persona.nombre = "Carlos"; // Esto es válido
console.log(persona.nombre); // "Carlos"
Diferencias entre var y let
Al empezar con JavaScript es común no tener claras las diferencias entre var y let. Ambas se usan para declarar variables, pero tienen diferencias importantes en cuanto a su alcance, hoisting y comportamiento dentro de bloques de código.
Usualmente, es preferible usar let o const en lugar de var para evitar posibles errores de alcance y comportamiento inesperado en el código.
Ámbito (scope)
var: Tiene scope de función o global, lo que significa que si declaras una variable convardentro de una función, solo será accesible dentro de esa función, pero si se declara fuera de una función, será global. Sin embargo, dentro de bloques (if,for, etc.), las variablesvarsiguen siendo accesibles fuera del bloque.let: Tiene scope de bloque, lo que significa que solo será accesible dentro del bloque de código en el que se ha declarado. Esto incluye bloques de control comoif,for,while, etc.
if (true) {
var x = 5;
let y = 10;
}
console.log(x); // 5
console.log(y); // ReferenceError: y is not defined
Hoisting
var: Las variables declaradas convarse hoistean, lo que significa que su declaración "se eleva" al principio del contexto de ejecución (función o global), aunque no su inicialización. Esto puede llevar a comportamientos inesperados.let: Las variables declaradas conlettambién se hoistean, pero no se inicializan, y están en una zona temporalmente muerta (TDZ, Temporal Dead Zone) hasta que se ejecuta su declaración en el código.
console.log(a); // undefined (porque var es hoisted)
var a = 3;
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 3;
El hoisting no es que el código se "mueva hacia arriba" realmente, sino que durante la fase de compilación el motor de JavaScript registra las declaraciones (no las asignaciones) de variables y funciones antes de ejecutar el código.
El hoisting en JavaScript afecta de manera distinta a funciones declaradas, var, let y const.
Redefinición
var: Puedes redeclarar la misma variable varias veces en el mismo ámbito sin error.let: No puedes redeclarar una variable en el mismo ámbito si ya ha sido declarada conlet. Intentarlo lanzará un error.
var x = 1;
var x = 2; // No hay problema
let y = 1;
let y = 2; // SyntaxError: Identifier 'y' has already been declared
Comportamiento en loops
var: Cuando se usavaren un buble comofor, la variable es compartida entre todas las iteraciones.let: En cambio,letcrea una nueva variable para cada iteración del buble, lo que es útil para capturar el valor correcto dentro de funciones de callback o closures.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // Imprime 3, 3, 3
}
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // Imprime 0, 1, 2
}
Resumen
| Declaración | Ámbito | Mutabilidad | Comentarios |
|---|---|---|---|
var | Función o global | Puede reasignarse | Forma histórica; no recomendable en código moderno por su comportamiento de hoisting y ámbito poco predecible. |
let | Bloque ({}) | Puede reasignarse | Introducida en ES6; recomendable para variables que cambian de valor. |
const | Bloque ({}) | No puede reasignarse | Para valores constantes o referencias inmutables; no hace inmutable el objeto, solo la referencia. |
Buenas prácticas
- Usar
constpor defecto,letsolo si vas a reasignar. - Evitar
var. - Nombrar variables de forma clara (
camelCasees estándar en JS). - Evitar variables globales innecesarias.