W3docs

JavaScript globalThis e o Objeto Global

Aprenda o objeto global do JavaScript: globalThis vs window vs global, o que contém, por que var e funções de nível superior vazam para ele e como evitar poluir o namespace global.

Todo programa JavaScript é executado dentro de um objeto de nível superior que existe antes de o seu código começar: o objeto global. Ele contém os recursos nativos da linguagem (Array, Math, JSON, setTimeout, etc.) e é o destino implícito de tudo o que você declara no topo de um script clássico. Esta página explica o que é o objeto global, como acessá-lo de forma portável com globalThis, o que realmente existe nele, por que algumas declarações de nível superior "vazam" para ele enquanto outras não, e como manter seus próprios globais sob controle.

O que é o objeto global

O objeto global é a raiz da cadeia de escopos. Quando você referencia um nome que não é encontrado em nenhuma função ou escopo de bloco envolvente, o motor finalmente o procura como uma propriedade do objeto global. É por isso que Math.max ou JSON.parse funcionam em qualquer lugar — eles são propriedades do objeto global que o ambiente de execução configura para você.

Cada ambiente de execução expõe esse objeto com um nome diferente, o que historicamente tornava o código entre ambientes complicado:

  • Navegadores chamam de window (e também expõem self e frames).
  • Web Workers chamam de self (não há window em um worker).
  • Node.js chama de global.

globalThis: o global portável

Como o nome varia por ambiente, o ES2020 adicionou globalThis — uma única referência padrão que aponta para o objeto global em todos os lugares: navegadores, workers, Node.js, Deno e mais. Use-o sempre que precisar do objeto global real em código que deve ser executado em mais de um lugar.

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.js

Tentar usar o nome errado lança um ReferenceError, que é exatamente o problema que globalThis resolve:

javascript— editable

Para uma visão mais ampla do que um ambiente hospedeiro adiciona sobre a linguagem, veja o ambiente do navegador e especificações.

O que existe no objeto global

O objeto global carrega dois tipos de coisas:

  1. Recursos nativos da linguagem, definidos pela especificação ECMAScript e presentes em todos os lugares: Object, Array, Function, String, Number, Boolean, Symbol, BigInt, Math, JSON, Date, RegExp, Promise, Map, Set, os construtores de erros e funções globais como parseInt, isNaN e eval.
  2. APIs do host (ambiente), adicionadas pelo ambiente de execução: document, fetch, localStorage, setTimeout e alert no navegador; process, Buffer e require no 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 que var e funções de nível superior vazam para o objeto global

Em um script de navegador clássico (não-módulo), um var declarado no nível superior e uma declaração de função de nível superior se tornam propriedades de window. Este é um comportamento legado incorporado na linguagem por compatibilidade retroativa:

// 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"

Declarações com escopo de bloco se comportam de forma diferente. let, const e class no nível superior criam ligações globais, mas não se anexam ao 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 variable

Duas ressalvas importantes:

  • Módulos ES não vazam de forma alguma. Declarações de var e function de nível superior dentro de um <script type="module"> (ou qualquer arquivo com import/export) têm escopo de módulo, então nada — nem mesmo var — se anexa ao objeto global.
  • Arquivos Node.js também são módulos. Um var de nível superior em um arquivo .js do Node tem escopo naquele módulo, portanto não se anexa a global como um script de navegador clássico faria.

Essa diferença é uma das razões práticas pelas quais o código moderno prefere let/const e módulos. Para a história completa de hoisting e escopo por trás do var, leia o antigo "var" e escopo de variável e closure.

Evitando poluição global

Globais são estado compartilhado e mutável: qualquer script pode sobrescrevê-los, e colisões de nomes causam bugs difíceis de rastrear. Alguns hábitos mantêm o namespace limpo:

  • Prefira let/const e módulos. Eles mantêm as declarações completamente fora do objeto global.
  • Use um único namespace quando você realmente precisar de um global, para que você adicione uma propriedade em vez de muitas.
  • Ative o modo estrito. "use strict" faz com que uma atribuição não declarada como x = 5 lance um erro em vez de criar silenciosamente um global.
javascript— editable

Módulos ES mantêm o namespace global limpo

Módulos ES dividem o código em arquivos reutilizáveis cujas declarações de nível superior permanecem privadas para cada arquivo, a menos que sejam explicitamente exportadas. Esta é a alternativa moderna a anexar coisas ao 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.

Conclusão

O objeto global é o escopo raiz do ambiente de execução: ele hospeda os recursos nativos da linguagem e as APIs do host e, em scripts clássicos, também coleta declarações de var e function de nível superior. Use globalThis para acessá-lo de forma portável, apoie-se em let/const e módulos para evitar poluí-lo, e ative o modo estrito para detectar globais acidentais logo cedo.

Prática

Prática
Quais das seguintes são boas práticas ao usar o objeto global em JavaScript?
Quais das seguintes são boas práticas ao usar o objeto global em JavaScript?
Was this page helpful?