Javascript 如果全局变量没有';不存在于ES5严格吗?
我正在ES5中编写ES HarmonyJavascript 如果全局变量没有';不存在于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; //
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() {
// ...
};
})();