Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如果全局变量没有';不存在于ES5严格吗?_Javascript_Ecmascript 5 - Fatal编程技术网

Javascript 如果全局变量没有';不存在于ES5严格吗?

Javascript 如果全局变量没有';不存在于ES5严格吗?,javascript,ecmascript-5,Javascript,Ecmascript 5,我正在ES5中编写ES HarmonySymbol/Name的实现。我将使用名称Symbol,但我希望浏览器使用它已经存在的任何Symbol(在未来的浏览器中)。我想我的代码是ES5严格兼容和移植到其他项目 在ES3/ES5非严格版中,有一种(多种)方法可以实现我的目标: (function() { // If Symbol already exists, we're done. if(typeof Symbol != 'undefined') return; //

我正在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() {
        // ...
    };

})();
但是,它不是严格符合ES5的,因为没有明确定义
Symbol


实现这一点的其他方法包括访问
窗口
对象(
window.Symbol=…
),但这也不好,因为我不希望我的代码假定它在浏览器环境中运行

如何在ES5中做到这一点

'use strict';

var Symbol = 1; // try to comment this line and run the script again

var Symbol = (function(Symbol) {


    if(typeof Symbol != 'undefined') return Symbol;

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

    return Symbol;

})(Symbol);

alert(typeof Symbol);


为什么它需要在匿名函数中

// assuming global context
if (typeof this.Symbol === 'undefined') {
    this.Symbol = function () {
        // ...
    };
}
或者在函数中,按说明传递此


传入要添加符号的全局范围如何

(function(global){
 if(typeof global.Symbol != 'undefined') return;

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

})(window);  

这会将它添加到窗口中,但可能是其他范围或变量。

其他用户发布的答案导致我提出了类似的StackOverflow问题,该问题为我提供了在谷歌中搜索以找到答案的正确术语。解决方案:

我最终能够通过使用一个,描述的解决这个问题

根据ES5规范,使用间接求值(在上面链接的文章中有详细介绍)在全局范围内执行代码。我选择使用这种方法,因为它符合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() {
        // ...
    };

})();
关键是使用间接的
eval
检索全局对象(
在间接的
eval
上下文中使用此

这应该适用于任何符合ES5的环境,包括我所希望的现代浏览器和非浏览器环境

谢谢大家的帮助


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

“实现这一点的其他方法包括访问窗口对象(window.Symbol=…),但这也不好,因为我不希望我的代码假定它在浏览器环境中运行。“这是一个很好的尝试,但我认为由于
var
的提升,它并没有真正起作用。将
Symbol
替换为真正存在的东西,比如
Array
,看看我的意思:这看起来是一个很有吸引力的可能性。我有几个问题。(1)这真的符合ES5的严格要求吗?如果从全局范围运行,默认情况下,这将是ES5中的全局对象吗?(2)这在非浏览器环境(如Node.js)中有效吗?节点中全局范围内的
是否指全局对象?这是ES5规范的行为部分吗?谢谢!不,在节点
中,此
不指
全局
对象。在节点中,您可以在我的示例中明确使用
全局
,而不是
窗口
。在节点
控制台中。log(this,this===global,this===module);
将输出
{}false
我安装了节点并对其进行了测试。
this===global
对我来说是
true
。+1。谢谢你的帮助。最终不是我选择的解决方案,但它帮助我指出了一些好的地方。我写了“global scope”但不一定必须是全局变量,这取决于包装器的调用位置/方式。我考虑过这一点,这可能是我的最佳选择,但并不理想,因为对于非浏览器环境,它需要对文件进行编辑。我非常熟悉AMD(requirejs使用的模型),因为我自己为工作编写了一个实现。这如何解决我的问题?你只是指使用导出的能力?我想写一些可以放在任何地方的东西。我不想依赖模块模型。是的,我是指使用导出的能力。你想在某个地方定义符号,然后在其他地方选择和使用。Crea使用全局变量可能是一种不好的做法,因此,如果您同意遵循某些模式/impl,比如requirejs,那么至少有一种文档化的、半标准化的方法,您可以遵循这种方法,这样其他可能需要维护代码的人就不需要通过通心粉代码来处理。但我并不真的想定义一个全局变量。我想为某些事情提供一个垫片ng将在ES6中提供,以便其他LIB今天可以使用它。在ES6中,他们不必
要求
它。作为一个垫片,它不必是
require
d.+1,谢谢。你发布的链接,以及它激发的几次谷歌搜索最终让我找到了我想要的答案。这似乎是有目的的“严格模式使得不可能意外地创建全局变量”(将错误转换为错误),因为“在浏览器中公开全局对象是一种安全隐患”。(“保护”JavaScript)
(function(global){
 if(typeof global.Symbol != 'undefined') return;

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

})(window);  
(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() {
        // ...
    };

})();