只有在ES5严格不存在的情况下才能定义全局变量?

Nat*_*all 5 javascript ecmascript-5

我正在ES5中编写ES Harmony Symbol/ 的实现Name.我将使用该名称Symbol,但我希望浏览器Symbol在它已经存在的情况下(在未来的浏览器中)使用任何预先存在的名称.我希望我的代码符合ES5严格要求并可移植到其他项目中.

这是(非常多的)在ES3/ES5非严格中做我想做的事情的一种方式:

(function() {

    // If Symbol already exists, we're done.
    if(typeof Symbol != 'undefined') return;

    // This becomes global because it wasn't declared with var
    Symbol = function() {
        // ...
    };

})();
Run Code Online (Sandbox Code Playgroud)

但是,它不是ES5严格兼容的,因为Symbol没有明确定义.

实现此window目的的其他方法包括访问object(window.Symbol = ...),但这也不好,因为我不希望我的代码假设它在浏览器环境中运行.

如何在ES5中严格执行此操作?

Nat*_*all 4

其他用户发布的答案让我想到了一个类似的 StackOverflow 问题,它为我提供了在 Google 中搜索的正确术语以找到答案。解决方案:

我最终能够通过使用间接评估来解决这个问题,如下所述

根据 ES5 规范,使用间接 eval在全局范围内执行代码(上面链接的文章中有详细介绍)。我选择采用这种方法是因为它符合 ES5 规范,并且它允许代码从字面上被删除到任何地方,即使是在包管理器的另一个函数中,并且仍然找到全局对象(提供的其他答案无法做到这一点) )。

解决方案是这样的:

(function() {

    'use strict';

    var _global = (0, eval)('this');

    // If Symbol is already defined, there's nothing to do.
    if(_global.Symbol) return;

    _global.Symbol = function() {
        // ...
    };

})();
Run Code Online (Sandbox Code Playgroud)

关键是使用间接eval来检索全局对象(this在间接的上下文中eval)。

正如我所希望的,这应该适用于任何兼容 ES5 的环境,包括现代浏览器和非浏览器环境。

谢谢各位的帮助!

eval唯一需要注意的是,为了访问全局对象,必须以这种间接方式(现在更糟)使用(这已经够糟糕了)似乎有点黑客行为。规范中是否应该global包含标识符或其他访问全局对象的方法?