在ECMAScript 6中全局范围内的`this`

时间:2012-11-16 22:25:07

标签: javascript ecmascript-5 ecmascript-harmony

我已经尝试过自己查看ES6草案了,但我不知道该去哪看:

有人能告诉我ES6中的this是否必然引用全局对象?此外,此对象是否与全局范围具有相同的成员?

如果你能回答ES5也会有所帮助。

我知道全局范围内的this是指浏览器和大多数其他ES环境中的全局对象,如Node。我只是想知道这是规范定义的行为,还是实现者已添加的扩展行为(如果这种行为在ES6实现中继续)。另外,全局对象总是与全局范围相同吗?或者有区别吗?


更新 - 为什么我想知道:我基本上试图弄清楚如何在ES5&中可靠地获取全局对象6.我不能依赖window,因为这是浏览器特有的,我也不能依赖global,因为这是特定于Node等环境的。我知道Node中的this可以在模块范围内引用module,但我认为它仍然在全局范围内引用global。我想要一个跨环境的ES5&获得全局对象的6种兼容方式(如果可能)。似乎在我所知道的this全局范围内的所有环境中,但是我想知道它是否是实际规范的一部分(在我可能不熟悉的任何环境中都是如此可靠)。 / p>

我还需要知道全局范围和全局对象是否与规范相同。换句话说,全局范围内的所有变量都与globalobject.variable_name相同吗?


更新2 - 我正在尝试做什么:

我开发了一些ES6 shims for ES5 environments。我想知道(1)检查ES6内置函数是否已经存在以便在可能的情况下使用它们而不是我的垫片,以及(2)将垫片添加到全局范围内的最佳方法(1) 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)向该对象添加属性是否允许我将变量添加到全局范围?

2 个答案:

答案 0 :(得分:2)

是的,全局范围内的this将继续引用ES6中的全局对象。 (通常,ES6应该是完全向后兼容的,即任何保证在ES5中工作的代码也应该在ES6中工作)。

然而,“全球范围”的概念将不再与ES6中的全球对象相同。它引入了词法范围的新声明表单(letconstclassmodule等等。上次会议的结论是,这些都不会作为全球对象的属性出现。这有多种技术和方法上的原因,但最重要的是最好避免直接使用全局对象(这一直是正确的,但在ES6中更是如此)。

您是否需要特定的全局对象?

答案 1 :(得分:0)

大部分是的。

在任何非对象(或非集合this)中传递this将引用全局对象:

(function( global ){ /* do stuff! */ }(this));

此行为旨在保留在ES6中(可理解的向后兼容性问题)。这就是我所知道的大多数多平台(浏览器/节点)插件正在访问全局对象的方式。例如:https://github.com/documentcloud/underscore/blob/master/underscore.js#L12

尽管如此,服务器上的插件只能访问this module(导出)。但是,这就是你想要的节点。您的全局空间不会被清除(除非手动完成或服务器重启)。所以它在所有客户端连接之间共享;将任何东西分配给全球空间真的不是一个好主意。


javascript“version”之间处理this的方式唯一值得注意的区别在于strict mode,如果nullundefined通过则会引发错误到callapplybind(在this value的位置)。在非严格模式下,this仅被强制转换为全局对象。

"use strict";
foo.apply(null); // Throw error

希望这有帮助!