Introducción
En JavaScript, el ámbito (scope) y los closures son conceptos fundamentales que permiten controlar la visibilidad y la vida útil de las variables. Comprender estos conceptos es crucial para escribir código eficiente y evitar errores comunes. En esta lección, exploraremos estos temas en profundidad.
Ámbito (Scope)
El ámbito se refiere al contexto en el que las variables y funciones son accesibles. JavaScript tiene dos tipos principales de ámbito:
- Ámbito Global: Las variables definidas fuera de cualquier función o bloque tienen un ámbito global y son accesibles desde cualquier parte del código.
- Ámbito Local: Las variables definidas dentro de una función o bloque tienen un ámbito local y solo son accesibles dentro de esa función o bloque.
Ejemplo de Ámbito Global y Local
// Variable global var globalVar = "Soy una variable global"; function myFunction() { // Variable local var localVar = "Soy una variable local"; console.log(globalVar); // Accede a la variable global console.log(localVar); // Accede a la variable local } myFunction(); console.log(globalVar); // Accede a la variable global console.log(localVar); // Error: localVar no está definida en el ámbito global
Ámbito de Bloque
Con la introducción de let
y const
en ES6, JavaScript también soporta el ámbito de bloque. Las variables declaradas con let
o const
dentro de un bloque ({}
) solo son accesibles dentro de ese bloque.
if (true) { let blockVar = "Soy una variable de bloque"; console.log(blockVar); // Accede a la variable de bloque } console.log(blockVar); // Error: blockVar no está definida fuera del bloque
Closures
Un closure es una función que recuerda el ámbito en el que fue creada, incluso después de que ese ámbito haya terminado. Los closures permiten que una función acceda a variables de su ámbito externo incluso después de que la función externa haya terminado de ejecutarse.
Ejemplo de Closure
function outerFunction() { var outerVar = "Soy una variable externa"; function innerFunction() { console.log(outerVar); // Accede a la variable externa } return innerFunction; } const closureFunction = outerFunction(); closureFunction(); // "Soy una variable externa"
En este ejemplo, innerFunction
es un closure que recuerda el ámbito de outerFunction
, permitiéndole acceder a outerVar
incluso después de que outerFunction
haya terminado de ejecutarse.
Ejemplo Práctico de Closure
Los closures son útiles para crear funciones privadas y mantener el estado entre llamadas a funciones.
function createCounter() { let count = 0; return function() { count++; return count; }; } const counter = createCounter(); console.log(counter()); // 1 console.log(counter()); // 2 console.log(counter()); // 3
En este ejemplo, createCounter
devuelve una función que incrementa y devuelve el valor de count
. La variable count
se mantiene en el ámbito de la función devuelta, permitiendo que su valor se conserve entre llamadas.
Ejercicios Prácticos
Ejercicio 1: Ámbito de Variables
- Declara una variable global llamada
globalMessage
con el valor"Hola, mundo!"
. - Crea una función llamada
showMessage
que declare una variable local llamadalocalMessage
con el valor"Hola, desde la función!"
. - Dentro de
showMessage
, imprime ambas variables. - Llama a
showMessage
y luego intenta imprimirlocalMessage
fuera de la función.
// Solución var globalMessage = "Hola, mundo!"; function showMessage() { var localMessage = "Hola, desde la función!"; console.log(globalMessage); // "Hola, mundo!" console.log(localMessage); // "Hola, desde la función!" } showMessage(); console.log(localMessage); // Error: localMessage no está definida
Ejercicio 2: Creación de un Closure
- Crea una función llamada
createMultiplier
que tome un número como argumento y devuelva una función. - La función devuelta debe tomar otro número como argumento y devolver el producto de ambos números.
// Solución function createMultiplier(multiplier) { return function(number) { return number * multiplier; }; } const double = createMultiplier(2); console.log(double(5)); // 10 const triple = createMultiplier(3); console.log(triple(5)); // 15
Resumen
En esta lección, hemos explorado el ámbito y los closures en JavaScript. Hemos aprendido sobre los diferentes tipos de ámbito (global, local y de bloque) y cómo los closures permiten que las funciones recuerden el ámbito en el que fueron creadas. Estos conceptos son fundamentales para escribir código eficiente y mantener el control sobre la visibilidad y la vida útil de las variables.
En la próxima lección, profundizaremos en las funciones de orden superior, que son funciones que pueden tomar otras funciones como argumentos o devolverlas como resultados. ¡Sigue adelante y sigue aprendiendo!
JavaScript: De Principiante a Avanzado
Módulo 1: Introducción a JavaScript
- ¿Qué es JavaScript?
- Configuración de tu Entorno de Desarrollo
- Tu Primer Programa en JavaScript
- Sintaxis y Conceptos Básicos de JavaScript
- Variables y Tipos de Datos
- Operadores Básicos
Módulo 2: Estructuras de Control
- Sentencias Condicionales
- Bucles: for, while, do-while
- Sentencias Switch
- Manejo de Errores con try-catch
Módulo 3: Funciones
- Definición y Llamada de Funciones
- Expresiones de Función y Funciones Flecha
- Parámetros y Valores de Retorno
- Ámbito y Closures
- Funciones de Orden Superior
Módulo 4: Objetos y Arrays
- Introducción a los Objetos
- Métodos de Objeto y la Palabra Clave 'this'
- Arrays: Conceptos Básicos y Métodos
- Iteración sobre Arrays
- Desestructuración de Arrays
Módulo 5: Objetos y Funciones Avanzadas
- Prototipos y Herencia
- Clases y Programación Orientada a Objetos
- Módulos e Importación/Exportación
- JavaScript Asíncrono: Callbacks
- Promesas y Async/Await
Módulo 6: El Modelo de Objetos del Documento (DOM)
- Introducción al DOM
- Selección y Manipulación de Elementos del DOM
- Manejo de Eventos
- Creación y Eliminación de Elementos del DOM
- Manejo y Validación de Formularios
Módulo 7: APIs del Navegador y Temas Avanzados
- Almacenamiento Local y de Sesión
- Fetch API y AJAX
- WebSockets
- Service Workers y Aplicaciones Web Progresivas (PWAs)
- Introducción a WebAssembly
Módulo 8: Pruebas y Depuración
- Depuración de JavaScript
- Pruebas Unitarias con Jest
- Pruebas de Integración
- Pruebas de Extremo a Extremo con Cypress
Módulo 9: Rendimiento y Optimización
- Optimización del Rendimiento de JavaScript
- Gestión de Memoria
- Manipulación Eficiente del DOM
- Carga Perezosa y División de Código
Módulo 10: Frameworks y Librerías de JavaScript
- Introducción a React
- Gestión de Estado con Redux
- Conceptos Básicos de Vue.js
- Conceptos Básicos de Angular
- Elegir el Framework Adecuado