2019 年更新
使用当今所有的 Webpacks 和 Broccolis、Gulps 和 Grunts、TypeScripts 和 AltScripts 以及 create-react-apps 等,这是非常无用的,但是如果您只是使用普通的、旧的、VanillaJS 并且您想要制作它同构,这可能是你最好的选择:
var global
try {
global = Function('return this')();
} catch(e) {
global = window;
}
即使--use_strict
在节点中使用,函数构造函数调用也能工作,因为函数构造函数总是在全局非严格范围内执行。
如果 Function 构造函数失败,那是因为您使用的浏览器eval
被 CSP 标头禁用。
当然,随着 Deno 的进行(节点替换),他们也可能会禁止 Function 构造函数,在这种情况下,它会返回到枚举对象,例如global
, module
, exports
, globalThis
and window
,然后是鸭子类型检查,这是全局的彻底...... :-/
疯狂的单行解决方案(原创):
var global = Function('return this')() || (42, eval)('this');
.
.
.
作品
- 在每个环境中(我测试过)
- 在严格模式下
- 甚至在嵌套范围内
2014 年 9 月 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