Obtendo uma referência ao object global em um ambiente desconhecido no modo estrito

Qual é a maneira recomendada de obter um identificador para o object global no modo estrito do ES5 em um ambiente de host desconhecido ?

O ECMAScript não fornece uma maneira interna de referenciar o object global que eu conheço. Se isso acontecer, esta é a resposta que estou procurando.

Em um ambiente conhecido , o object global geralmente tem uma propriedade auto-referencial. Como o object global é o VO para o escopo global, as propriedades do object global são variables ​​globais, portanto, podemos usá-las para obter um identificador para o object global de qualquer lugar:

  • Em um navegador da web, podemos usar window ou self .

  • Em node.js, podemos usar global .

No entanto, isso não é necessariamente o caso em todos os ambientes de host. Tanto quanto sei, o Windows Script Host não fornece qualquer maneira de acessar o object global. A maneira recomendada de obter o object global no WSH parece ser usar a palavra this chave this em um contexto em que ela não é resolvida para um object. Por exemplo:

 var GLOBAL = (function(){return this}()); 

Essa técnica funcionará para qualquer ambiente de host, mas não no modo estrito, porque um indefinido não faz referência ao object global no modo estrito :

Se isso for avaliado no código de modo estrito, o valor this não será forçado para um object. Um valor nulo ou indefinido não é convertido no object global e os valores primitivos não são convertidos em objects de invólucro. O valor desse valor passado por meio de uma chamada de function (incluindo chamadas feitas usando Function.prototype.apply e Function.prototype.call) não coagem o valor passado para um object (10.4.3, 11.1.1, 15.3.4.3, 15.3. 4.4).

Conforme esperado, os seguintes resultados de código são undefined :

 (function(){ "use strict"; var GLOBAL = (function(){return this}()); console.log(GLOBAL); }()); 

Então, qual é a maneira correta de obter um identificador para o object global em qualquer ambiente, independentemente do modo estrito ?

By the way, a minha abordagem atual é para farejar variables ​​globais referenciando o object global como este:

 var self, window, global = global || window || self; 

… e depois é só usar global . Eu acho que esta é uma solução ruim por uma série de razões, a maioria das quais é bastante óbvia, e não resolve o problema do WSH.

No ES5, você pode obter uma referência ao object global de dentro do modo estrito por meio da chamada indireta eval:

 "use strict"; var global = (1,eval)('this'); 

Dê uma olhada no meu artigo ; particularmente nesta seção no modo estrito .

No código global , o thisBinding é definido como o object global, independentemente do modo estrito. Isso significa que você pode passar de lá para o seu módulo IEFE:

 // "use strict"; or not (function(global) { "use strict"; … console.log(global); … }(this)); 

No modo estrito, a maneira de obter uma referência ao object global é atribuir uma variável no próprio object global referenciando-se.

Isso é this significa o object global quando no contexto global , então a solução é simplesmente:

 "use strict"; var global = global || this; (function() { global.hello = "world"; })(); console.log(hello); // Outputs 'world' as expected 

Isso significa que você precisa poluir o namespace global com uma referência a si mesmo, mas, como você diz, ele já deveria estar lá.