我开始读JavaScript Patterns,一些codes把我搞糊涂了。
var global = (function () {
return this || (1, eval)('this');
}());以下是我的问题:
Q1:
(1, eval) === eval?
为什么?它是如何工作的?
Q2:为什么不直接
var global = (function () {
return this || eval('this');
}());或
var global = (function () {
return this;
}());发布于 2012-02-02 12:58:19
(1,eval)和普通的旧式eval之间的区别在于前者是一个值,而后者是一个左值。如果它是其他的标识符,那就更明显了:
var x;
x = 1;
(1, x) = 1; // syntax error, of course!也就是说,(1,eval)是一个产生eval的表达式(就像(true && eval)或(0 ? 0 : eval)一样),但它不是对eval的引用。
你为什么这么在意?
好吧,Ecma规范认为对eval的引用是一个“直接eval调用”,但是一个只产生间接1次间接eval调用的eval的表达式保证在全局范围内执行。
我仍然不知道的事情:
this调用不会在全局范围内执行?更多信息可以通过here获取。
编辑
显然,我第一个问题的答案是,“几乎总是”。直接eval从当前作用域执行。考虑以下代码:
var x = 'outer';
(function() {
var x = 'inner';
eval('console.log("direct call: " + x)');
(1,eval)('console.log("indirect call: " + x)');
})();不出所料(嘿嘿),这打印出来了:
direct call: inner
indirect call: outer编辑
经过更多的实验后,我暂时说this不能设置为null或undefined。它可以设置为其他错误的值(0、'‘、NaN、false),但只能非常有意地设置。
我要说的是,你的消息来源正在遭受轻微的可逆性颅骨直肠内翻,可能需要考虑花一周的时间在Haskell编程。
发布于 2012-02-02 13:17:18
片段
var global = (function () {
return this || (1, eval)('this');
}()); 将正确计算为全局对象,即使在严格模式下也是如此。在非严格模式下,this的值是全局对象,但在严格模式下,它是undefined。表达式(1, eval)('this')将始终是全局对象。
这样做的原因涉及到间接与直接eval之间的规则。对eval的直接调用具有调用者的作用域,字符串this将计算为闭包中的this的值。间接eval在全局范围内进行计算,就好像它们是在全局范围内的函数内执行的一样。
由于该函数本身不是严格模式函数,因此将全局对象作为this传入,然后表达式'this'计算为全局对象。表达式(1, eval)只是强制eval成为间接对象并返回全局对象的一种奇特方式。
A1:(1, eval)('this')与eval('this')不同,因为对eval的间接调用和直接调用有特殊的规则。
A2:原始版本在严格模式下工作,修改后的版本不能。
发布于 2012-02-02 12:46:34
致Q1:
我认为这是JS中逗号操作符的一个很好的例子。我喜欢本文中对逗号运算符的解释:http://javascriptweblog.wordpress.com/2011/04/04/the-javascript-comma-operator/
逗号运算符将计算其两个操作数(从左到右),并返回第二个操作数的值。
致Q2:
(1, eval)('this')被认为是间接的eval调用,在ES5中它确实是全局执行代码。因此,结果将是全局上下文。
请参阅http://perfectionkills.com/global-eval-what-are-the-options/#evaling_in_global_scope
https://stackoverflow.com/questions/9107240
复制相似问题