Saltar al contenido principal

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.

Hoisting

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 con var dentro 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 variables var siguen 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 como if, 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 con var se 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 con let tambié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 proceso real de hoisting

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 con let. 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 usa var en un buble como for, la variable es compartida entre todas las iteraciones.
  • let: En cambio, let crea 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ÁmbitoMutabilidadComentarios
varFunción o globalPuede reasignarseForma histórica; no recomendable en código moderno por su comportamiento de hoisting y ámbito poco predecible.
letBloque ({})Puede reasignarseIntroducida en ES6; recomendable para variables que cambian de valor.
constBloque ({})No puede reasignarsePara valores constantes o referencias inmutables; no hace inmutable el objeto, solo la referencia.

Buenas prácticas

  • Usar const por defecto, let solo si vas a reasignar.
  • Evitar var.
  • Nombrar variables de forma clara (camelCase es estándar en JS).
  • Evitar variables globales innecesarias.