Ответ 1
В ES5 вы можете получить ссылку на глобальный объект из строгого режима через косвенный вызов eval:
"use strict";
var global = (1,eval)('this');
Взгляните на мою статью; особенно в разделе строгого режима.
Какой рекомендуемый способ получить дескриптор глобального объекта в строгом режиме 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.
В ES5 вы можете получить ссылку на глобальный объект из строгого режима через косвенный вызов eval:
"use strict";
var global = (1,eval)('this');
Взгляните на мою статью; особенно в разделе строгого режима.
В глобальном коде, thisBinding
устанавливается на глобальный объект независимо от строгого режима. Это означает, что вы можете передать это оттуда в свой модуль IEFE:
// "use strict"; or not
(function(global) {
"use strict";
…
console.log(global);
…
}(this));
В строгом режиме способ получения ссылки на глобальный объект заключается в назначении переменной в глобальном объекте, ссылающемся на себя.
Это this
означает глобальный объект в глобальном контексте, поэтому решение просто:
"use strict";
var global = global || this;
(function() { global.hello = "world"; })();
console.log(hello); // Outputs 'world' as expected
Это означает, что вы должны загрязнять глобальное пространство имен ссылкой на себя, но, как вы говорите, оно должно быть уже там.