Подтвердить что ты не робот

Получение ссылки на глобальный объект в неизвестной среде в строгом режиме

Какой рекомендуемый способ получить дескриптор глобального объекта в строгом режиме ES5 в неизвестной среде хоста?

ECMAScript не предоставляет встроенный способ ссылки на глобальный объект, о котором я знаю. Если это так, это ответ, который я ищу.

В известной среде глобальный объект обычно имеет свойство self-referential. Поскольку глобальный объект является VO для глобальной области, свойства глобального объекта являются глобальными переменными, поэтому мы можем использовать их, чтобы получить дескриптор глобального объекта из любого места:

  • В веб-браузере мы можем использовать window или self.

  • В node.js мы можем использовать global.

Однако это не обязательно во всех средах хоста. Насколько мне известно, Windows Script Host не предоставляет никакого способа доступа к глобальному объекту. Рекомендуемым способом получения глобального объекта в WSH является использование ключевого слова this в контексте, где он не разрешает объект. Например:

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

Этот метод будет работать для любой среды хоста, но не в строгом режиме, потому что undefined this не ссылается на глобальный объект в строгом режиме:

Если это оценивается в строгом режиме, то это значение не принуждается к объекту. Это значение null или undefined не преобразуется в глобальный объект, а примитивные значения не преобразуются в объекты-обертки. Это значение передается через вызов функции (включая вызовы, выполненные с использованием Function.prototype.apply и Function.prototype.call) не принуждает переданное значение к объекту (10.4.3, 11.1.1, 15.3.4.3, 15.3. 4.4).

Как и ожидалось, следующий код приводит к undefined:

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

Итак, каков правильный способ получить дескриптор глобального объекта в любой среде, независимо от строгого режима?

Кстати, мой нынешний подход - обнюхивать глобальные переменные, ссылающиеся на глобальный объект следующим образом:

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

... а затем просто используйте global. Я думаю, что это плохое решение по ряду причин, большинство из которых достаточно очевидны и не затрагивает проблему WSH.

4b9b3361

Ответ 1

В ES5 вы можете получить ссылку на глобальный объект из строгого режима через косвенный вызов eval:

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

Взгляните на мою статью; особенно в разделе строгого режима.

Ответ 2

В глобальном коде, thisBinding устанавливается на глобальный объект независимо от строгого режима. Это означает, что вы можете передать это оттуда в свой модуль IEFE:

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

Ответ 3

В строгом режиме способ получения ссылки на глобальный объект заключается в назначении переменной в глобальном объекте, ссылающемся на себя.

Это this означает глобальный объект в глобальном контексте, поэтому решение просто:

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

Это означает, что вы должны загрязнять глобальное пространство имен ссылкой на себя, но, как вы говорите, оно должно быть уже там.