Skip to content

Lección 28: Scope (Ámbito de Variables)

El scope (ámbito) determina dónde una variable es accesible en tu código. JavaScript tiene tres tipos principales de scope:

Variables declaradas fuera de cualquier función o bloque. Accesibles desde cualquier parte del código.

const globalVar = 'Soy global';
function test() {
console.log(globalVar); // "Soy global"
}

Variables declaradas dentro de una función. Solo accesibles dentro de esa función.

function miFuncion() {
var localVar = 'Soy local';
console.log(localVar); // "Soy local"
}
// console.log(localVar); // ReferenceError

Variables declaradas con let o const dentro de {} (if, for, while). Solo existen dentro de ese bloque.

if (true) {
let bloqueVar = 'Solo aquí';
const otraVar = 'También solo aquí';
var functionVar = 'Esta escapa del bloque';
}
console.log(functionVar); // "Esta escapa del bloque"
// console.log(bloqueVar); // ReferenceError

JavaScript busca variables hacia arriba en la cadena de scopes anidados:

const global = '🌍';
function exterior() {
const outer = '🌳';
function interior() {
const inner = '🌱';
console.log(inner); // encuentra aquí
console.log(outer); // busca en el padre
console.log(global); // busca en el abuelo
}
interior();
}
exterior();

Ocurre cuando una variable en un scope interno tiene el mismo nombre que una en el scope externo, “ocultándola”:

let nombre = 'Global';
function test() {
let nombre = 'Local'; // shadowing
console.log(nombre); // "Local"
}
test();
console.log(nombre); // "Global"
var x = 1; // global
let y = 2; // global (pero no en window)
if (true) {
var x = 10; // misma variable, la reasigna
let y = 20; // nueva variable, solo en el bloque
console.log(x); // 10
console.log(y); // 20
}
console.log(x); // 10 (var modificó la global)
console.log(y); // 2 (let intacta en su scope)

var tiene function scope, no block scope. let y const tienen block scope. Esta es la razón principal por la que var está en desuso en favor de let/const.

for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // 3, 3, 3 (var global)
}
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 100); // 0, 1, 2 (let por iteración)
}

Regla de oro: usa const por defecto, let cuando necesites reasignar, y nunca uses var en código moderno. Esto previene bugs relacionados con el scope y hace tu código más predecible.

¿Qué imprime el siguiente código? Escríbelo y ejecútalo para verificar.

const mensaje = 'Fuera';
function padre() {
const mensaje = 'Padre';
function hijo() {
console.log(mensaje);
}
hijo();
}
padre(); // ¿Qué imprime?
console.log(mensaje); // ¿Y esto?