5

我自己尝试过查看 ES6 草案,但我不确定在哪里查看:

有人可以告诉我this在 ES6 中是否一定指的是全局对象?此外,该对象是否具有与全局范围相同的成员?

如果你能回答 ES5,那也会很有帮助。

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


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

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


更新 2 - 我正在尝试做的事情:

为 ES5 环境开发了一些 ES6 垫片。我想知道 (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) 向该对象添加属性是否允许我将变量添加到全局范围?

4

2 回答 2

2

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

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

有什么特定的东西需要全局对象吗?

于 2012-11-17T09:54:03.923 回答
0

大部分是的。

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

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

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

虽然,服务器上的插件确实只能this作为module(导出)访问。但是,这就是你在 node.js 中想要的。您的全局空间永远不会被清理(除非手动完成,或者在服务器重新启动时)。所以它在所有客户端连接之间共享;将任何东西分配给全局空间确实不是一个好主意。


thisjavascript“版本”之间处理方式的唯一显着区别是 in strict mode,它将引发错误的是 if nullorundefined被传递给callor applyor bind(在 的位置this value)。在非严格模式下,this只被强制到全局对象。

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

希望这有帮助!

于 2012-11-17T05:32:00.693 回答