Back

Una Guía Rápida sobre el Ámbito Global de JavaScript

Una Guía Rápida sobre el Ámbito Global de JavaScript

Cuando declaras una variable en el nivel superior de un archivo JavaScript, ¿dónde reside realmente? La respuesta depende de si estás escribiendo un script clásico o un módulo ES—y equivocarse en esto conduce a errores sutiles que son frustrantes de depurar.

Esta guía explica cómo funciona el ámbito global de JavaScript en el desarrollo moderno, por qué globalThis es la forma confiable de referenciar el objeto global, y cómo var, let y const se comportan de manera diferente en el nivel superior.

Puntos Clave

  • El comportamiento del ámbito global difiere entre scripts clásicos y módulos ES—solo var en scripts clásicos crea propiedades en el objeto global.
  • let y const crean enlaces globales pero no se adjuntan al objeto global.
  • Usa globalThis para compatibilidad entre entornos cuando necesites acceder al objeto global.
  • Prefiere los módulos ES para aislamiento automático de ámbito y evitar la contaminación no intencionada del espacio de nombres.

¿Qué Es el Ámbito Global de JavaScript?

El ámbito global se refiere al ámbito más externo en tu entorno JavaScript. Las variables en ámbito global son accesibles desde cualquier lugar de tu código—dentro de funciones, bloques o módulos anidados.

Pero aquí está la distinción crítica que la mayoría de los tutoriales omiten: el ámbito de nivel superior en JavaScript se comporta de manera diferente dependiendo de cómo se carga tu script.

Scripts Clásicos vs Módulos ES

En un script clásico (cargado sin type="module"), las variables de nivel superior declaradas con var se convierten en propiedades del objeto global:

// classic script
var config = { debug: true }
console.log(globalThis.config) // { debug: true }

Con los módulos ES, esto cambia completamente. Los módulos y el ámbito global funcionan de manera diferente por diseño. Los enlaces de nivel superior en un módulo permanecen dentro del ámbito de ese módulo—no se adjuntan al objeto global:

// module script (type="module")
var config = { debug: true }
console.log(globalThis.config) // undefined

Este aislamiento es intencional. Los módulos proporcionan encapsulación, previniendo la contaminación accidental del espacio de nombres entre archivos. Consulta la guía de MDN sobre módulos JavaScript para una referencia más profunda.

Cómo Difieren var, let y const en el Nivel Superior

Incluso en scripts clásicos, let y const se comportan de manera diferente a var:

// classic script
var a = 1
let b = 2
const c = 3

console.log(globalThis.a) // 1
console.log(globalThis.b) // undefined
console.log(globalThis.c) // undefined

Solo var crea una propiedad en el objeto global. Tanto let como const crean enlaces en el ámbito global que son accesibles en todo tu código, pero no se convierten en propiedades del objeto global.

Esta distinción importa cuando scripts de terceros esperan encontrar tus variables en el objeto global, o cuando estás depurando y verificándolo directamente.

Por Qué globalThis Es el Estándar Moderno

Diferentes entornos JavaScript históricamente usaban nombres diferentes para el objeto global:

  • Los navegadores usan window
  • Node.js usa global
  • Los Web Workers usan self

Escribir código multiplataforma significaba verificar qué global existía. El estándar globalThis resuelve esto proporcionando una referencia universal:

// Works everywhere
globalThis.sharedValue = 'accessible across environments'

Usar globalThis asegura que tu código se ejecute correctamente ya sea en un navegador, Node.js, Deno o un Web Worker. Es el enfoque correcto y agnóstico de plataforma.

Sombreado de Variables en el Ámbito Global

Un concepto erróneo común: no puedes redeclarar una variable let o const que ya existe en el ámbito global. Sin embargo, puedes sombrear enlaces var introducidos globalmente con declaraciones léxicas—incluyendo enlaces var introducidos dinámicamente (por ejemplo, mediante eval) en motores modernos:

var x = 1
{
  let x = 2 // shadows the global var
  console.log(x) // 2
}
console.log(x) // 1

El let x interno crea una variable separada que oculta temporalmente el var x externo dentro de ese bloque. Son enlaces distintos—modificar uno no afecta al otro.

Características Exclusivas de Módulos: Top-Level Await

Una diferencia práctica con el ámbito de nivel superior que los desarrolladores JavaScript deben conocer: await en el nivel superior solo funciona en módulos:

// Only valid in modules
const data = await fetch('/api/config').then(r => r.json())

Los scripts clásicos no soportan esta sintaxis. Si necesitas await de nivel superior, debes usar type="module" en tu etiqueta script.

Mejores Prácticas para el Ámbito Global

  1. Prefiere los módulos — Proporcionan aislamiento automático de ámbito e importaciones/exportaciones explícitas
  2. Usa globalThis — Cuando genuinamente necesites el objeto global, esto funciona en todas partes
  3. Evita var en el nivel superior — Usa let o const para prevenir la contaminación no intencionada del objeto global
  4. Sé explícito sobre las globales — Si algo debe ser global, adjúntalo a globalThis intencionalmente en lugar de depender del comportamiento implícito

Conclusión

El ámbito global en JavaScript no es tan simple como “variables accesibles en todas partes”. Los scripts clásicos y los módulos ES manejan los enlaces de nivel superior de manera diferente, y solo var en scripts clásicos crea propiedades del objeto global. Usa globalThis para compatibilidad entre entornos, y prefiere los módulos por su encapsulación incorporada. Comprender estas distinciones te ayuda a escribir código predecible que funciona en diferentes entornos JavaScript.

Preguntas Frecuentes

Sí, pero solo si ambos scripts son scripts clásicos y comparten el mismo ámbito global. Las variables son accesibles por nombre entre scripts, pero no son propiedades del objeto global. Si cualquiera de los scripts es un módulo ES, las variables permanecen privadas a ese módulo a menos que se exporten explícitamente.

Usa el objeto global cuando necesites compartir datos con scripts que no controlas, como analíticas de terceros o código heredado que espera globales. También úsalo para polyfills que deben estar disponibles universalmente. Para código que controlas, prefiere las exportaciones de módulo para mejor encapsulación y seguimiento explícito de dependencias.

globalThis es compatible con todos los entornos JavaScript modernos. Si debes dar soporte a plataformas heredadas como Internet Explorer, usa un polyfill o confía en tu empaquetador/transpilador para proporcionar uno.

Esta es una decisión de diseño histórica. var fue parte de JavaScript desde el principio y fue diseñado para crear propiedades del objeto global para interoperabilidad. let y const se introdujeron en ES6 con reglas de ámbito más estrictas para evitar los problemas de la contaminación global implícita mientras aún permiten accesibilidad global.