En este artículo, obtendrás información sobre el alcance y cómo funciona en JavaScript.
El alcance es un concepto fundamental en JavaScript y otros lenguajes de programación que define el contexto en el que se accede a las variables y se usan. A medida que continúas aprendiendo JavaScript y trabajando más con variables, se vuelve más útil y aplicable a tu código.
El alcance puede ayudarte a lograr lo siguiente:
- Usa la memoria de manera más eficiente: El permiso proporciona la capacidad de cargar variables solo cuando es necesario. Si una variable está fuera del alcance, no es necesario que la pongas a disposición del código que se está ejecutando actualmente.
- Encuentra y corrige errores con mayor facilidad: Aislar variables con alcance local facilita la solución de errores en tu código porque, a diferencia de las variables globales, puedes confiar en que el código desde un alcance externo no puede manipular variables con alcance local.
- Crea pequeños bloques de código reutilizable: Por ejemplo, puedes escribir una función pura que no dependa de un alcance externo. Puedes mover fácilmente esa función a otro lugar con cambios mínimos.
¿Qué es el alcance?
El alcance de una variable determina desde qué parte del código puedes usar una variable.
JavaScript define variables de alcance global o local:
- Las variables con alcance global están disponibles desde todos los demás alcances en el código de JavaScript.
- Las variables con alcance local solo están disponibles dentro de un contexto local específico y se crean a partir de palabras clave, como
var
,let
yconst
. Si usas las palabras clavevar
,let
oconst
para crear una variable dentro de una función, esa variable tiene alcance local.
En las secciones posteriores de este artículo, se analiza el alcance léxico y el bloque:
- Las variables de alcance del bloque están disponibles de forma local para un bloque, según lo determinado por la ubicación de las llaves en la que se define la sentencia de bloque. Solo las variables declaradas con las palabras clave
let
oconst
tienen alcance de bloque. - El alcance léxico usa la ubicación donde se declara una variable en el código fuente para determinar dónde está disponible. Usa cierres para otorgar a una función delimitada acceso a las variables a las que se hace referencia en el alcance externo conocido como entorno léxico.
Cuando se accede a una variable dentro de su alcance, JavaScript muestra su valor asignado o produce un error.
Para declarar una variable, haz lo siguiente:
- Usa las palabras clave
var
,const
olet
para declarar variables de alcance local o global. - Usa las palabras clave
const
olet
para declarar variables de alcance de bloque.
Cuando declaras una variable var
en una función, la declaración hace que la variable esté disponible para la función delimitante más cercana. No puedes usar la palabra clave var
para declarar variables con alcance de bloque.
Ejemplos de alcance
En este ejemplo, se muestra el alcance global porque la variable greeting
se declara fuera de cualquier función o bloque, lo que hace que su valor esté disponible para todo el código del documento actual:
const greeting = 'hello';
console.log(greeting); // 'hello'
En el ejemplo de alcance global, a la variable greeting
se le asigna un valor hello
.
En este ejemplo, se muestra el alcance local porque declara la variable greeting
con la palabra clave let
dentro de una función. La variable greeting
es una variable de alcance local y no está disponible fuera de la función.
function greet() {
let greeting = 'Hello World!';
console.log(greeting);
}
En este ejemplo, se muestra el alcance del bloque porque declara la variable greeting
dentro de un bloque para que solo se pueda acceder a la variable entre llaves:
if (true) {
const greeting = 'hello';
}
console.log(greeting); // ReferenceError: greeting is not defined
Ten en cuenta que cuando la función console.log
intenta generar el valor de la variable greeting
, JavaScript muestra un mensaje de error ReferenceError
en lugar del mensaje hello
esperado. ¿Por qué?
Se muestra un error porque la variable greeting
tiene alcance de bloque y el bloque más cercano es parte de la sentencia condicional if
. No puedes acceder a las variables let
y const
que declaras dentro de un bloque desde fuera del bloque. Por lo tanto, solo puedes acceder a la variable greeting
entre llaves, que especifica el alcance del bloque.
En este ejemplo, se corrige el error, ya que mueve el método console.log(message)
dentro de las llaves. El código actualizado reubica el método console.log(message)
dentro del bloque.
if (true) {
const greeting = 'hello';
console.log(greeting);
}
Tipos de alcances
Alcance global
Puedes acceder a variables con alcance global desde cualquier parte del programa.
Considera un archivo HTML que importa dos archivos JavaScript: file-1.js
y file-2.js
:
<script src="file-1.js"></script>
<script src="file-2.js"></script>
En este ejemplo, la variable globalMessage
tiene un alcance global y se escribe fuera de una función. Durante la ejecución y la ejecución, puedes acceder al valor de la variable globalMessage
desde cualquier parte del programa de JavaScript.
Puedes ver el contenido de los archivos file-1.js
y file-2.js
en este fragmento de código. Observa la disponibilidad de la variable globalMessage
en ambos archivos.
// file-1.js
function hello() {
var localMessage = 'Hello!';
}
var globalMessage = 'Hey there!';
// file-2.js
console.log(localMessage); // localMessage is not defined
console.log(globalMessage); // Hey there!
Hay otro tipo de alcance que no se analiza demasiado en este artículo. Si creas una variable dentro de un módulo de JavaScript, pero fuera de una función o un bloque, no tiene alcance global, sino alcance del módulo. Las variables con alcance del módulo están disponibles en cualquier lugar del módulo actual, pero no lo están en otros archivos o módulos. Para hacer que una variable con alcance de módulo esté disponible para otros archivos, debes exportarla desde el módulo en el que se creó y, luego, import desde el módulo que necesita acceder a la variable.
Alcance local y alcance de la función
Cuando creas variables en una función de JavaScript con las palabras clave var
, let
o const
, las variables son locales para la función, por lo que solo puedes acceder a ellas desde dentro de ella. Las variables locales se crean cuando se inicia una función y se borran de manera efectiva cuando finaliza su ejecución.
En este ejemplo, se declara la variable total
en la función addNumbers()
. Solo puedes acceder a las variables a
, b,
y total
dentro de la función addNumbers()
.
function addNumbers(a, b) {
const total = a + b;
}
addNumbers(3, 4);
Puedes usar las palabras clave let
y const
para asignar nombres a las variables. Cuando usas la palabra clave let
, JavaScript puede actualizar la variable. Sin embargo, con la palabra clave const
, la variable permanece constante.
var variable1 = 'Declared with var';
var variable1 = 'Redeclared with var';
variable1; // Redeclared with var
let variable2 = 'Declared with let. Cannot be redeclared.';
variable2 = 'let cannot be redeclared, but can be updated';
variable2; // let cannot be redeclared, but can be updated
const variable3 = 'Declared with const. Cannot be redeclared or updated';
variable3; // Declared with const. Cannot be redeclared or updated
Bloquear el alcance
Los bloques se usan para agrupar una sola sentencia o un conjunto de sentencias. Puedes usar las palabras clave const
o let
para declarar una variable local con alcance de bloque. Ten en cuenta que no puedes usar la palabra clave var
para declarar variables con alcance de bloque.
Por ejemplo, en este bloque, el alcance de la variable name
y su valor "Elizabeth"
se incluyen entre llaves. Las variables dentro del alcance de un bloque no están disponibles fuera del bloque.
{
const name = "Elizabeth";
}
Puedes usar variables de alcance de bloque en sentencias if
, for
o while
.
Toma nota de los dos bucles for
dentro de este fragmento de código. Un bucle for
usa la palabra clave var
para declarar la variable de inicializador, que aumenta a través de los números 0
, 1
y 2
. El otro bucle for
usa la palabra clave let
para declarar la variable de inicializador.
for (var i = 0; i < 2; i++) {
// ...
}
console.log(i); // 2
for (let j = 0; j < 2; j++) {
// ...
}
console.log(j); // The j variable isn't defined.
En el ejemplo de código anterior, puedes observar que la variable i
del primer bucle for
se filtró fuera del bucle for
y aún conserva un valor 2
porque la palabra clave var
no usa el alcance de bloque. El problema se corrigió en el segundo bucle for
, en el que la variable j
declarada con la palabra clave let
se limita al bloque del bucle for
y no existe después de que finaliza el bucle for
.
Reutilización de un nombre de variable en un alcance diferente
El alcance puede aislar una variable dentro de una función, incluso cuando reutilizas el mismo nombre de variable en otro lugar de un alcance diferente.
En este ejemplo, se muestra cómo el uso del alcance te permite reutilizar el mismo nombre de variable en diferentes funciones:
function listOne() {
let listItems = 10;
console.log(listItems); // 10
}
function listTwo() {
let listItems = 20;
console.log(listItems); // 20
}
listOne();
listTwo();
A las variables listItems
en las funciones listOne()
y listTwo()
se les asignan los valores esperados y, por lo tanto, no entran en conflicto entre sí.
Cierres y alcance léxico
Los cierres hacen referencia a una función delimitada en la que una función interna puede acceder al alcance de la función exterior, que también se conoce como entorno léxico. Por lo tanto, en JavaScript, usas cierres para permitir que las funciones hagan referencia al entorno léxico externo, que permite que el código dentro de una función haga referencia a variables declaradas fuera de la función. De hecho, puedes programar una cadena de referencias a entornos léxicos externos para que una función llame a una función y, a su vez, otra función la llame.
En este ejemplo, el código forma un cierre con el entorno léxico que se crea cuando se invoca la función outer()
, que se cierra sobre la variable hello
. Por lo tanto, la variable hello
se usa dentro de la función de devolución de llamada setTimeout
.
function outer() {
const hello = 'world';
setTimeout(function () {
console.log('Within the closure!', hello)
}, 100);
}
outer();
Con el alcance léxico, el alcance se determina durante la compilación del código fuente, no en el tiempo de ejecución. Para obtener más información sobre el entorno léxico, consulta Alcance y cierre léxicos.
Módulos
Los módulos de JavaScript ayudan a organizar el código. Si se usan correctamente, proporcionan una estructura eficaz a tu base de código y ayudan a reutilizarlo. En lugar de usar variables globales para compartir variables entre diferentes archivos, los módulos de JavaScript proporcionan una técnica para importar y import.
// hello.js file
function hello() {
return 'Hello world!';
}
export { hello };
// app.js file
import { hello } from './hello.js';
console.log(hello()); // Hello world!
Demostración del visualizador de permisos
El alcance es un concepto fundamental que todo desarrollador de JavaScript debe comprender. Para comprender mejor el sistema de permisos, puedes intentar escribir tu propio código con JS Scope Visualizer. En la demostración, se usan colores en el código para ayudarte a visualizar los alcances de JavaScript.
Conclusión
En este artículo, se presentan diferentes tipos de alcances. El alcance de JavaScript es uno de los conceptos más avanzados dentro del desarrollo web, por lo que es genial que hayas leído este contenido y te hayas tomado el tiempo para comprender este tema.
El alcance no es una función para el usuario. Solo afecta al desarrollador web que escribe el código, pero conocer cómo funciona el alcance puede ayudarte a corregir los errores que surjan.