Um novo padrão para o objeto global no JavaScript

Cofundador da @BrazilJS e da @NascHQ, Software developer e autor/editor no portal BrazilJS.

O objeto global no JavaScript é, no mínimo, peculiar. Muitos novatos na linguagem acabam cometendo erros graves por não saberem exatamente como o objeto global funciona. Até mesmo programadores experientes em outras linguagens podem enfrentar dificuldades em entender e utilizar o objeto global.

Vejamos o exemplo abaixo:

function calc(x, y) { 
   a = x + y; 
   b = 3; 
   c = a + b;

   return c; 

}

Este código funciona perfeitamente e, ao chamar a função calc(1,2), o resultado será o esperado 6.

O JavaScript permite que variáveis sejam criadas sem a utilização das keywords var, let ou const. Porém, ao omiti-las, estamos colocando estas variáveis no objeto global. No caso do navegador, ao executar a função calc estamos criando as variáveis a, b e c no objeto global window.

window.a // 3
window.b // 3
window.c // 6

Por este e por outros motivos, é sempre recomendado utilizar o strict mode, que basicamente define uma semântica mais restrita ao JavaScript.

function calc(x, y) { 
    "use strict"; 
    a = x + y; 
    b = 3; 
    c = a + b;

    return c; 

}

Ao chamar a função calc com a definição use strict no seu corpo, teremos o seguinte erro: Uncaught ReferenceError: a is not defined. Isto porque o strict mode não permite que variáveis sejam definidas sem o uso de var, let ou const.

No ambiente do Node.js o problema é o mesmo, com a diferença de que o objeto global não é o window, mas sim o global.

Objeto global no Node.js


Objeto global no Node.js

É mais complicado do que isso

O objeto global ainda pode ser acessado de outras formas, dependendo do contexto.

this

O this, no escopo global do navegador, irá sempre referenciar ao objeto window. Já no ambiente Node.js, isso não irá funcionar, pois módulos no Node.js possuem o seu próprio escopo. E ainda existem mais diferenças relacionadas ao this e à maneira de chamar funções. O artigo do Dr. Axel Rauschmayer sobre global mostra ainda mais exemplos. O Felipe Moura também tem um artigo bem completo sobre o this.

self

A variável global self funciona em iframes, janelas, Web Workers, Service Workers, porém, não funciona no ambiente Node.js.

Estão me acompanhando aqui? Já deu pra notar que não existe uma maneira padrão para acessar o objeto global independentemente do ambiente, certo? Obviamente, a comunidade criou soluções alternativas, como o exemplo abaixo:

(typeof window !== "undefined" ? window : (typeof process === 'object' && typeof require === 'function' && typeof global === 'object') ? global : this); 

A verdade é que até hoje não temos um standard para acesso ao objeto global, mas isso está prestes a mudar.

A proposta

Jordan Harband é o autor da proposta que irá introduzir ao objeto global a variável global. A especificação já está no estágio 3 do processo do TC-39 e, ao que tudo indica, já poderemos utilizar o global na ES2017. O autor da especificação criou um polyfill para que seja possível já utilizar e testar o global hoje.

// Computing the value of `global` 
import getGlobal from 'system.global'; 
const global = getGlobal();

// Shimming `global` (“installing” it) import shim from ‘system.global/shim’; 
shim();

Conclusão

A ES2015 e ES2016 trouxeram uma série de correções e melhorias para o JavaScript, mas a linguagem continua constantemente evoluindo. Existem atualmente uma série de propostas que, assim como o global, estão em estágio 3. O global facilitará o entendimento de como o objeto global funciona e principalmente possibilitará a interoperabilidade em navegadores e no Node.js.

Vale lembrar que o processo de evolução da especificação do JavaScript passa por 4 fases, tendo como objetivo validar propostas, expor para a comunidade e garantir através de pesquisas e testes que a funcionalidade/melhoria não irá quebrar a Web. Isso ocorreu com o global e está explícito na documentação:

Further research has determined that using global will not break existing code

Traduzindo, “Uma pesquisa adicional determinou que o uso do global não irá quebrar códigos existentes”.

Referências

ES proposal: global proposal-global TC-39 proposal global


BrazilJS é uma iniciativa NASC