JavaScript globalThis y el objeto global
Aprende el objeto global de JavaScript: globalThis vs window vs global, qué contiene, por qué var y funciones de nivel superior se filtran a él, y cómo evitar contaminar el espacio de nombres global.
Todo programa JavaScript se ejecuta dentro de un objeto de nivel superior que existe antes de que tu código comience: el objeto global. Contiene los tipos y funciones integrados del lenguaje (Array, Math, JSON, setTimeout, etc.) y es el hogar implícito de todo lo que declares en el nivel más alto de un script clásico. Esta página explica qué es el objeto global, cómo acceder a él de forma portable con globalThis, qué contiene exactamente, por qué algunas declaraciones de nivel superior se "filtran" a él mientras otras no, y cómo mantener tus propios globales bajo control.
Qué es el objeto global
El objeto global es la raíz de la cadena de ámbitos. Cuando haces referencia a un nombre que no se encuentra en ningún ámbito de función o bloque superior, el motor finalmente lo busca como una propiedad del objeto global. Por eso Math.max o JSON.parse funcionan en cualquier parte: son propiedades del objeto global que el entorno de ejecución configura por ti.
Cada entorno de ejecución expone ese objeto bajo un nombre diferente, lo que históricamente hacía que el código entre entornos fuera complicado:
- Los navegadores lo llaman
window(y también exponenselfyframes). - Los Web Workers lo llaman
self(no existewindowen un worker). - Node.js lo llama
global.
globalThis: el global portable
Debido a que el nombre difiere según el entorno, ES2020 añadió globalThis — una referencia estándar única que apunta al objeto global en todos lados: navegadores, workers, Node.js, Deno y más. Úsala siempre que necesites el objeto global real en código que deba ejecutarse en más de un entorno.
console.log(typeof globalThis); // "object" in every environment
// Each of these is true only in its own environment:
// globalThis === window -> true in a browser tab
// globalThis === self -> true in a browser or a Web Worker
// globalThis === global -> true in Node.jsIntentar usar el nombre incorrecto lanza un ReferenceError, que es exactamente el problema que globalThis resuelve:
Para ver el panorama más amplio de lo que un entorno host añade sobre el lenguaje, consulta el entorno del navegador y las especificaciones.
Qué contiene el objeto global
El objeto global contiene dos tipos de elementos:
- Tipos y funciones integrados del lenguaje, definidos por la especificación ECMAScript y presentes en todos lados:
Object,Array,Function,String,Number,Boolean,Symbol,BigInt,Math,JSON,Date,RegExp,Promise,Map,Set, los constructores de error y funciones globales comoparseInt,isNaNyeval. - APIs del host (entorno), añadidas por el entorno de ejecución:
document,fetch,localStorage,setTimeoutyalerten el navegador;process,Bufferyrequireen Node.js.
// Built-ins are reachable through the global object:
console.log(globalThis.Math.max(2, 7, 4)); // 7
console.log(globalThis.JSON.stringify({ ok: true })); // {"ok":true}Por qué var y las funciones de nivel superior se filtran al objeto global
En un script de navegador clásico (no módulo), una var declarada en el nivel superior y una declaración de función de nivel superior se convierten en propiedades de window. Este es un comportamiento heredado incorporado al lenguaje por compatibilidad hacia atrás:
// In a classic browser script (not a module):
var greeting = 'hi';
function greet() { return greeting; }
console.log(window.greeting); // "hi"
console.log(typeof window.greet); // "function"Las declaraciones con ámbito de bloque se comportan de manera diferente. let, const y class en el nivel superior crean enlaces globales pero no se adjuntan al objeto global:
let count = 1;
const name = 'app';
console.log(window.count); // undefined
console.log(window.name); // "" — note: window.name is a pre-existing browser property, not your variableDos advertencias importantes:
- Los módulos ES no se filtran en absoluto. Las declaraciones de
varyfunctionde nivel superior dentro de un<script type="module">(o cualquier archivo conimport/export) tienen ámbito de módulo, por lo que nada — ni siquieravar— se adjunta al objeto global. - Los archivos de Node.js también son módulos. Una
varde nivel superior en un archivo.jsde Node tiene ámbito en ese módulo, por lo que no se adjunta aglobalcomo lo haría un script de navegador clásico.
Esta diferencia es una de las razones prácticas por las que el código moderno prefiere let/const y módulos. Para conocer la historia completa de hoisting y ámbitos detrás de var, lee el antiguo "var" y ámbito de variables y clausuras.
Evitar la contaminación del espacio de nombres global
Los globales son estado compartido y mutable: cualquier script puede sobreescribirlos, y las colisiones de nombres causan errores difíciles de rastrear. Algunos hábitos mantienen el espacio de nombres limpio:
- Prefiere
let/consty módulos. Mantienen las declaraciones completamente fuera del objeto global. - Usa un único espacio de nombres cuando genuinamente necesites un global, para añadir una sola propiedad en lugar de muchas.
- Activa el modo estricto.
"use strict"hace que una asignación no declarada comox = 5lance un error en lugar de crear silenciosamente un global.
Los módulos ES mantienen limpio el espacio de nombres global
Los módulos ES dividen el código en archivos reutilizables cuyas declaraciones de nivel superior permanecen privadas para cada archivo a menos que se exporten explícitamente. Esta es la alternativa moderna a adjuntar cosas al objeto global:
// file: math.js
export const add = (a, b) => a + b;
// file: app.js
import { add } from './math.js';
console.log(add(2, 3)); // 5
// `add` is imported, not read from a global — nothing leaks onto window/global.Conclusión
El objeto global es el ámbito raíz del entorno de ejecución: aloja los tipos y funciones integrados del lenguaje y las APIs del host, y en los scripts clásicos también recoge las declaraciones de var y function de nivel superior. Usa globalThis para acceder a él de forma portable, apóyate en let/const y módulos para evitar contaminarlo, y activa el modo estricto para detectar globales accidentales desde el principio.