Obter uma referência para o objeto global em um ambiente desconhecido no modo restrito
-
10-12-2019 - |
Pergunta
O que é a forma recomendada para obter um identificador para o objeto global em ES5 de modo estrito em um ambiente de host desconhecido?
ECMAScript não fornece um caminho para a referência de objecto global que eu estou ciente.Se não, esta é a resposta que eu estou procurando.
Em um conhecida ambiente, o objeto global, geralmente, tem uma auto-referencial propriedade.Desde que o objeto global é o VO para o escopo global, propriedades do objeto global são variáveis globais, para que possamos usá-los a obter um identificador para o objeto global a partir de qualquer lugar:
Em um navegador da web, podemos usar
window
ouself
.No node.js podemos usar
global
.
No entanto, este não é necessariamente o caso em todos os ambientes de host.Até onde eu sei, o Windows Script Host não fornece qualquer forma de acesso a objetos globais.A forma recomendada para obter o objeto global no WSH parece ser a de usar o this
palavras-chave em um contexto onde não resolver para um objeto.Por exemplo:
var GLOBAL = (function(){return this}());
Essa técnica funciona para qualquer ambiente de host, mas não no modo estrito, porque um indefinido this
não faz referência ao objeto global em de modo estrito:
Se esta é avaliada dentro de modo estrito código e, em seguida, este valor não é coagido a um objeto. Um valor nulo ou não definido não é convertido para o objeto global e valores primitivos não são convertidos para objetos de wrapper.A este valor passado através de uma chamada de função (incluindo as chamadas feitas usando a Função.protótipo.aplicar e Função.protótipo.chamar) não forçar o passado esse valor para um objeto (10.4.3, 11.1.1, 15.3.4.3, 15.3.4.4).
Como esperado, o código a seguir resulta em undefined
:
(function(){
"use strict";
var GLOBAL = (function(){return this}());
console.log(GLOBAL);
}());
Então, qual é a forma correta para obter um identificador para o objeto global em qualquer ambiente, independentemente do modo estrito?
Pelo jeito, a minha abordagem atual é de cheirar para variáveis globais referência global objeto como este:
var self, window, global = global || window || self;
...e depois é só usar global
.Eu acho que isso é uma má solução para um número de razões, a maioria dos quais são bastante óbvias, e que não resolve o WSH problema.
Solução
Em ES5, você pode obter uma referência para o objeto global partir de dentro, de modo estrito via indireta eval chamada:
"use strict";
var global = (1,eval)('this');
Dê uma olhada no meu artigo;particularmente neste secção no modo estrito.
Outras dicas
No código global, o thisBinding
é definido para o objeto global, independentemente do modo estrito.Isso significa que você pode passá-lo de lá, em seu módulo IEFE:
// "use strict"; or not
(function(global) {
"use strict";
…
console.log(global);
…
}(this));
No modo estrito, o caminho para obter uma referência para o objeto global é atribuir a uma variável global objeto de referência de si mesmo.
Que é this
significa que o objeto global quando no contexto global, então a solução é simples:
"use strict";
var global = global || this;
(function() { global.hello = "world"; })();
console.log(hello); // Outputs 'world' as expected
Este não significa que você tem que poluir o espaço de nomes global com uma referência a si mesmo, mas como você disse, ele já deve ter sido lá.