【发布时间】:2012-11-05 16:40:06
【问题描述】:
我自己尝试过查看 ES6 草案,但不确定在哪里查看:
谁能告诉我 ES6 中的 this 是否一定指的是全局对象?另外,这个对象会和全局作用域有相同的成员吗?
如果你能回答 ES5,那也会很有帮助。
我知道this 在全局范围内指的是浏览器和大多数其他 ES 环境中的全局对象,例如 Node.js。我只想知道这是规范定义的行为,还是实现者添加的扩展行为(以及这种行为是否会在 ES6 实现中继续存在)。此外,全局对象是否总是与全局范围相同?还是有区别?
更新 - 为什么我想知道:我基本上是想弄清楚如何在 ES5 和 6 中可靠地获取全局对象。我不能依赖 window,因为那是特定于浏览器,我也不能依赖global,因为这是特定于 Node 等环境的。我知道 Node 中的 this 可以在模块范围内引用 module,但我认为它仍然是在全局范围内引用 global。我想要一种跨环境的 ES5 & 6 兼容方式来获取全局对象(如果可能的话)。似乎在我所知道的所有环境中 this 在全局范围内都是这样做的,但我想知道它是否是实际规范的一部分(并且在我可能不熟悉的任何环境中都如此可靠)。
我还需要知道规范中的全局范围和全局对象是否相同。换句话说,全局范围内的所有变量都会与globalobject.variable_name相同吗?
更新 2 - 我正在尝试做的事情:
我开发了一些ES6 shims for ES5 environments。我想知道 (1) 检查 ES6 内置插件是否已经存在,以便在可能的情况下可以使用它们而不是我的垫片,以及 (2) 如果内置 - 将我的垫片添加到全局范围内ins 尚不存在。
目前我正在遵循这种模式:
(function() {
// Indirect eval to run in global scope.
// (We get whatever "this" is in global scope, hoping that it's the global object...
// Whether this line does what I want it to is the crux of my question.)
var global = (0, eval)('this');
// If Symbol does not already exist in global scope,
if (!global.Symbol)
// Then add Symbol to global scope.
global.Symbol = (function() {
// ...
// Return my Symbol shim
})();
})();
(1)还有其他一些可能性,但归根结底,我需要一种在全局范围内不使用 var 的方式向全局范围添加一些内容(因为这会在我之前覆盖内置函数检查它们,因为var 提升[至少在幼稚的情况下,也许我也可以间接eval var 声明?])。我希望我的代码能够在严格模式下运行,从而使问题更加复杂。
我发现,根据 ES5 规范,间接 eval 在全局范围内执行代码。所以我至少能够做到这一点。我的问题是如果我在全局范围内获得this,(1)检查该对象的属性是否会让我知道全局范围内是否已经存在内置? (2) 向该对象添加属性是否允许我将变量添加到全局范围?
【问题讨论】:
-
它应该像以前的 ES 规范一样工作,因为
this不是 ES6 特定的。this的含义取决于它的使用位置,并不总是全局对象。 -
明白了;这就是为什么我问“在全局范围内”,在浏览器中
this与window相同,window也是全局对象。但是,我不知道这是在 ES 中指定的,还是只是该语言的浏览器扩展。 -
只要您不在 SES 之类的环境中,间接 eval 技巧就可以可靠地工作。拥有全局对象后,您可以分配给它并检查属性,这将满足您的要求。在 es6 中,除了 Andreas 所说的 let、const 等之外,还有一个问题是模块具有自己的私有全局,其具有主全局对象作为外部范围,因此除非直接引用,否则无法访问或修改外部全局提供给它(例如,自动定义“全局”的 node.js 会为您提供对该外部全局的引用)。
-
谢谢本维!有关模块的信息有助于了解。
标签: javascript ecmascript-5 ecmascript-harmony