我正在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() {
// ...
};
})();
但是,由于Symbol
未明确定义,因此不符合ES5标准。
实现此目的的其他方法包括访问window
对象(window.Symbol = ...
),但这也不好,因为我不希望我的代码假设它在浏览器环境中运行。 / p>
如何在严格的ES5中完成?
答案 0 :(得分:4)
其他用户发布的答案让我得到了类似的StackOverflow问题,该问题为我提供了在Google中搜索以找到答案的正确条款。解决方案:
我最终能够使用indirect eval来解决这个问题,描述为here。
使用上面链接的文章中详细介绍的间接评估,按照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
在间接this
的上下文中检索全局对象(eval
)。
这应该适用于符合ES5标准的任何内容,包括现代浏览器和非浏览器环境,正如我所希望的那样。
感谢所有人的帮助!
唯一需要注意的是,为了访问全局对象,必须以这种间接方式(现在更糟糕)使用eval
(这已经够糟糕了)似乎有点蠢蠢欲动。访问全局对象的global
标识符或其他方法是否不在规范中?
答案 1 :(得分:1)
'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);
http://jsfiddle.net/f0t0n/yATJW/
'use strict';
(function(g) { // g is a global context (this passed)
if(typeof g.Array != 'undefined') {
return;
}
g.Array = function() {
// ...
};
g.Array.prototype.foo = function() {
console.log('bar');
};
})(this);
console.log(this.Array);
答案 2 :(得分:1)
为什么需要使用匿名函数?
// assuming global context
if (typeof this.Symbol === 'undefined') {
this.Symbol = function () {
// ...
};
}
或在函数中,按照here
所述传递this
(function (t) {
if (typeof t.Symbol === 'undefined') {
t.Symbol = function () {
// ...
};
}
})(this);
答案 3 :(得分:1)
如何传递要将Symbol添加到的全局范围?
(function(global){
if(typeof global.Symbol != 'undefined') return;
// This becomes global because it wasn't declared with var
global.Symbol = function() {
// ...
};
})(window);
这会将其添加到窗口,但可能是其他范围或var。