Alcance y Closures
Alcance local vs global y closures
Alcance (Scope)
El alcance determina donde las variables son accesibles en tu codigo. JavaScript tiene alcance global, de funcion y de bloque.
Alcance Global
// Variables declaradas fuera de cualquier funcion
const global = "Soy global";
function mostrarGlobal() {
console.log(global); // Accesible
}
mostrarGlobal(); // "Soy global"
console.log(global); // "Soy global"
Alcance de Funcion
function miFuncion() {
const local = "Soy local";
console.log(local); // Accesible
}
miFuncion();
// console.log(local); // Error: local no esta definida
Alcance de Bloque (let/const)
if (true) {
let bloque = "Solo en este bloque";
const tambienBloque = "Yo tambien";
var noBloque = "Escapo del bloque"; // var no respeta alcance de bloque
}
// console.log(bloque); // Error
// console.log(tambienBloque); // Error
console.log(noBloque); // "Escapo del bloque" - por eso evitamos var
Closures
Un closure es una funcion que "recuerda" las variables de su alcance externo, incluso despues de que la funcion externa haya terminado de ejecutarse.
function crearContador() {
let cuenta = 0; // Variable privada
return function() {
cuenta++;
return cuenta;
};
}
const contador = crearContador();
console.log(contador()); // 1
console.log(contador()); // 2
console.log(contador()); // 3
// Cada llamada a crearContador crea un nuevo closure
const otroContador = crearContador();
console.log(otroContador()); // 1 (independiente)
Usos Practicos de Closures
// Encapsulacion de datos privados
function crearUsuario(nombre) {
let _nombre = nombre; // "privado"
return {
obtenerNombre: () => _nombre,
establecerNombre: (nuevoNombre) => { _nombre = nuevoNombre; }
};
}
const usuario = crearUsuario("Ana");
console.log(usuario.obtenerNombre()); // "Ana"
usuario.establecerNombre("Maria");
console.log(usuario.obtenerNombre()); // "Maria"
// console.log(usuario._nombre); // undefined - no accesible directamente
// Funciones de fabrica
function multiplicador(factor) {
return (numero) => numero * factor;
}
const duplicar = multiplicador(2);
const triplicar = multiplicador(3);
console.log(duplicar(5)); // 10
console.log(triplicar(5)); // 15
Puntos Clave
- Los closures "capturan" variables, no valores
- Utiles para crear datos privados y funciones de fabrica
- Cada closure tiene su propia copia del alcance externo
- Cuidado con closures en bucles - usa let en vez de var