Volver a la lista

let, var, const: diferencias en la declaración de variables

Explica claramente las diferencias entre los tres métodos de declaración de variables en JavaScript: `var`, `let` y `const`, desde la perspectiva del alcance (scope) y la reasignación.

Principiante
|
8min
|
Verificado (2026-07)
letvarconstdeclaración de variablesalcance de bloquealcance de función
Progreso0/55 (0%)

let, var, const — Diferencias en la declaración de variables

Al finalizar este tema

Podrás explicar las diferencias entre var, let y const desde las perspectivas del alcance (scope) y la reasignación, y podrás determinar qué utilizar en cada situación.


Las tres palabras clave de declaración

En JavaScript, existen tres formas de declarar variables:

javascript
var name = "Cheolsu";    // ES5 (estilo antiguo)
let age = 25;        // ES6 (2015~)
const PI = 3.14159;  // ES6 (2015~)

En todos los casos, se "crea un nombre que almacena un valor". La diferencia radica en el alcance (hasta dónde es visible) y la reasignación (si se puede cambiar el valor).


Posibilidad de reasignación

javascript
let count = 0;
count = 1;          // ✅ let permite reasignación

const MAX = 100;
MAX = 200;          // ❌ TypeError: Assignment to constant variable

const no puede ser reasignado después de su declaración; una vez asignado, el valor no se puede cambiar. let y var sí permiten la reasignación.

Nota: const significa que "el enlace de la variable es inmutable", no que "el valor sea inmutable". El contenido interno de objetos o arreglos puede modificarse:

javascript
const user = { name: "Cheolsu" };
user.name = "Younghee";  // ✅ Es posible modificar el interior del objeto
user = {};           // ❌ No es posible cambiar la variable en sí por otro valor

Ámbito — var frente a let/const

var tiene un ámbito de función. Ignora los bloques de las instrucciones if o for ({}):

javascript
function example() {
  if (true) {
    var x = 10;
  }
  console.log(x);  // 10 — ¡Es posible acceder fuera del bloque if!
}

let/const tienen alcance de bloque. Solo existen dentro del bloque declarado ({}):

javascript
function example() {
  if (true) {
    let y = 10;
  }
  console.log(y);  // ReferenceError: y is not defined
}

El alcance de bloque es intuitivo: solo existe dentro de las llaves donde se declara y desaparece fuera de ellas.


Diferencias en el bucle for

javascript
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Salida: 3, 3, 3  — Todos hacen referencia al mismo i

La variable declarada con var, i, ignora el bloque del bucle for; por lo tanto, cuando se ejecuta setTimeout, i ya ha alcanzado el valor 3.

javascript
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Salida: 0, 1, 2  — Cada iteración crea un nuevo i

let crea un nuevo bloque de ámbito en cada iteración, por lo que cada i existe de forma independiente. Esta es la diferencia más importante entre let y var.


Elevación (Hoisting)

La elevación (hoisting) es el fenómeno mediante el cual las declaraciones se mueven al inicio del código.

javascript
console.log(a);  // undefined (¡No es un error!)
var a = 5;

console.log(b);  // ReferenceError: Cannot access 'b' before initialization
let b = 5;

var se inicializa como undefined debido al hoisting de la declaración. Por lo tanto, acceder antes de la declaración no genera un error, lo que dificulta encontrar errores.

let y const también se someten a hoisting, pero generan un error si se accede a ellos antes de su inicialización. Este intervalo se denomina ZDT (Temporal Dead Zone). Es más ventajoso para la depuración que aparezcan errores.


Guías prácticas

javascript
// 1. El valor predeterminado es const
const API_URL = "https://api.example.com";
const users = [];

// 2. let solo cuando el valor deba cambiar
let count = 0;
count++;

// 3. No uses var
// (Solo visible en código legado)
Palabra claveÁmbitoReasignaciónElevación (Hoisting)Momento de uso
varFunciónSe inicializa como undefinedNo usar
letBloqueTDZ (error)Cuando el valor cambia
constBloqueTDZ (error)Valor por defecto

En JavaScript moderno, se debe usar const como valor predeterminado y cambiar a let solo cuando sea necesaria la reasignación. var permanece únicamente por razones históricas; no hay razón para usarlo en código nuevo.


El famoso error de las clausuras con var

El error más conocido que crea el ámbito de función de var:

javascript
// Quiero mostrar números diferentes para cada uno de los 5 botones
for (var i = 0; i < 5; i++) {
  document.getElementById("btn" + i).onclick = function() {
    alert(i);  // alerta 5 en todos los casos
  };
}

Todos los botones muestran 5. En el momento del clic, i ya es 5 porque todos los callbacks hacen referencia al mismo i.

javascript
// Se soluciona usando let
for (let i = 0; i < 5; i++) {
  document.getElementById("btn" + i).onclick = function() {
    alert(i);  // 0, 1, 2, 3, 4
  };
}

Como let crea un nuevo ámbito en cada iteración, cada devolución de llamada tiene su propia i. Antes de ES6, se utilizaba una IIFE (expresión de función ejecutada inmediatamente) como solución alternativa; con la introducción de let, este patrón ya no es necesario.


var/let/const en declaraciones de funciones

También existen diferencias dependiendo del método de declaración al crear funciones:

javascript
// Declaración de función — se eleva (hoisting)
greet();  // ✅ Funciona
function greet() {
  console.log("Hola");
}

// Expresión de función con const — no se eleva (no hoisting)
hello();  // ❌ ReferenceError
const hello = () => {
  console.log("Hola");
};

Las declaraciones de funciones pueden invocarse en cualquier parte del código, pero las funciones declaradas con const solo pueden invocarse después de su declaración. Por lo general, los proyectos unifican el uso de uno de estos enfoques.


Diferencias en el ámbito global

javascript
// En el entorno del navegador
var globalVar = "soy var";
let globalLet = "soy let";

console.log(window.globalVar);  // "soy var" — se añade al objeto window
console.log(window.globalLet);  // undefined — no se añade a window

Las variables globales declaradas con var se convierten en propiedades del objeto window. Esto puede causar conflictos de nombres entre bibliotecas. Las declaraciones de let y const en el ámbito global no se agregan a window.


Errores comunes y soluciones

javascript
// Error 1: modificar el interior de un objeto const es legal
const config = { debug: true };
config.debug = false;    // ✅ permitido — modificación del interior del objeto
config = {};             // ❌ no permitido — reasignación de la variable

// Error 2: usar const en un bucle for
for (const i = 0; i < 3; i++) {  // ❌ error de reasignación en i++
  console.log(i);
}

// En for...of se puede usar const (nueva vinculación en cada iteración)
for (const item of [1, 2, 3]) {  // ✅
  console.log(item);
}


Object.freeze: crear inmutabilidad real

const Para impedir realmente la modificación del interior de un objeto:

javascript
const config = Object.freeze({
  apiUrl: "https://api.example.com",
  maxRetries: 3
});

config.apiUrl = "changed";    // ignorado silenciosamente (error en modo estricto)
console.log(config.apiUrl);   // "https://api.example.com"

Object.freeze() impide la adición, modificación o eliminación de propiedades del objeto. Sin embargo, al ser una congelación superficial (shallow freeze), el contenido interno de los objetos anidados sigue siendo modificable.


Al leer código, si se ve const, se puede saber inmediatamente que "este valor no cambiará". Esta previsibilidad se vuelve cada vez más importante a medida que el proyecto crece.

💬 Preguntas y comentarios

0 comentarios

Puedes publicar sin iniciar sesión. Los comentarios de invitados no pueden editarse ni eliminarse después.

0/2000

Cargando...