Обновление 2019
Со всеми сегодняшними Webpacks и Broccolis, а также с Gulps and Grunts, TypeScripts и AltScripts, а также с приложениями create-реагировать и т. Д., Это довольно бесполезно, но если вы просто работаете с простым, старым, VanillaJS и вы хочу сделать его изоморфным, это, вероятно, ваш лучший вариант:
var global
try {
global = Function('return this')();
} catch(e) {
global = window;
}
Вызов конструктора функции будет работать даже при использовании --use_strict
в узле, поскольку конструктор функции всегда выполняется в глобальной нестрогой области.
Если конструктор Function завершается ошибкой, это потому, что вы находитесь в браузере с eval
, отключенным заголовками CSP.
Конечно, с Deno в пути (замена узла) они также могут запретить конструктор Function, и в этом случае он возвращается к перечислению таких объектов, как global
, module
, exports
, globalThis
и window
, а затем проверка типа утки, которая является глобальной ...: - /
Безумное однострочное решение (Оригинал):
var global = Function('return this')() || (42, eval)('this');
.
.
.
Работает
- в каждой среде (которую я тестировал)
- в строгом режиме
- и даже во вложенной области
Обновление 2014-сентябрь-23
Теперь это может завершиться ошибкой, если заголовки HTTP в последних браузерах явно запрещают eval.
Обходной путь может заключаться в том, чтобы попробовать / поймать оригинальное решение, поскольку известно, что только браузеры используют этот тип JavaScript.
var global;
try {
global = Function('return this')() || (42, eval)('this');
} catch(e) {
global = window;
}
Example:
---
(function () {
var global = Function('return this')() || (42, eval)('this');
console.log(global);
// es3 context is `global`, es5 is `null`
(function () {
"use strict";
var global = Function('return this')() || (42, eval)('this');
console.log(global);
}());
// es3 and es5 context is 'someNewContext'
(function () {
var global = Function('return this')() || (42, eval)('this');
console.log(global);
}).call('someNewContext');
}());
Tested:
---
* Chrome v12
* Node.JS v0.4.9
* Firefox v5
* MSIE 8
Why:
---
In short: it's some weird quirk. See the comments below (or the post above)
In `strict mode` `this` is never the global, but also in `strict mode` `eval` operates in a separate context in which `this` *is* always the global.
In non-strict mode `this` is the current context. If there is no current context, it assumes the global. An anonymous function has no context and hence in non-strict mode assumes the global.
Sub Rant:
There's a silly misfeature of JavaScript that 99.9% of the time just confuses people called the 'comma operator'.
var a = 0, b = 1;
a = 0, 1; // 1
(a = 0), 1; // 1
a = (0, 1); // 1
a = (42, eval); // eval
a('this'); // the global object