JavaScript中的(1,eval)('this')vs eval('this')?

时间:2012-02-02 04:38:00

标签: javascript eval

我开始阅读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;
}());

4 个答案:

答案 0 :(得分:91)

(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调用”,但这个表达只会使eval成为间接调用 - - 并保证间接eval调用在全局范围内执行。

我还不知道的事情:

  1. 在什么情况下直接评估在全球范围内执行?
  2. 在什么情况下,全局范围内的函数的this 会产生全局对象?
  3. 可以收集更多信息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无法设置为nullundefined。它可以设置为其他有价值的值(0,'',NaN,false),但只能非常

    我要说你的来源患有轻微且可逆的颅内直肠反转,并且可能想考虑在Haskell中花一周时间编程。

答案 1 :(得分:30)

片段,

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:原版在严格模式下工作,修改后的版本不工作。

答案 2 :(得分:11)

到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

答案 3 :(得分:7)

Q1:用逗号分隔的多个连续的javascript语句取最后一个语句的值。所以:

(1, eval)获取最后一个的值,该值是eval()函数的函数引用。它显然是这样做的,使eval()调用成为间接eval调用,将在ES5的全局范围内进行评估。细节解释here

Q2:必须有一些环境不能定义全局this,但确定eval('this')。这是我能想到的唯一原因。