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

sha*_*jia 80 javascript eval

我开始阅读JavaScript模式,一些代码让我困惑.

var global = (function () {
    return this || (1, eval)('this');
}());
Run Code Online (Sandbox Code Playgroud)

这是我的问题:

Q1:

(1, eval) === eval

为什么以及如何运作?

Q2:为什么不呢

var global = (function () {
    return this || eval('this');
}());
Run Code Online (Sandbox Code Playgroud)

要么

 var global = (function () {
    return this;
}());
Run Code Online (Sandbox Code Playgroud)

Mal*_*lio 95

(1,eval)和旧的区别在于eval前者是一个而后者是一个左值.如果是其他标识符会更明显:

var x;
x = 1;
(1, x) = 1; //  syntax error, of course!
Run Code Online (Sandbox Code Playgroud)

这是(1,eval)一个表达式eval(就像说,(true && eval)(0 ? 0 : eval)将会),但它不是一个引用eval.

你为什么在乎?

好了,规范了Ecma认为一个参考,以eval成为一个"直接的eval通话",但只是产生一个表达式eval是一间接一-和间接的eval调用保证了在全球范围内执行.

我还不知道的事情:

  1. 在什么情况下直接eval调用不在全局范围内执行?
  2. 在什么情况下this,全局范围内的函数不会产生全局对象?

可以在这里收集更多信息.

编辑

显然,我的第一个问题的答案是"几乎总是".直接eval当前范围执行.请考虑以下代码:

var x = 'outer';
(function() {
  var x = 'inner';
  eval('console.log("direct call: " + x)'); 
  (1,eval)('console.log("indirect call: " + x)'); 
})();
Run Code Online (Sandbox Code Playgroud)

毫不奇怪(嘿嘿),这打印出来:

direct call: inner
indirect call: outer
Run Code Online (Sandbox Code Playgroud)

编辑

经过更多的实验,我将暂时说this不能设置为nullundefined.它可以设置为其他假值(0,'',NaN,false),但只是非常刻意.

我要说你的来源患有轻度和可逆的颅 - 直肠反转,并且可能想考虑在Haskell中花一周的编程.

  • 哇,不知道整个'价值'与'左值'的事情(好吧,在实践中可能,但不是用语言).也不是ES5评估规则(不是我应该合理地使用`eval`).谢谢! (3认同)

chu*_*ckj 30

片段,

var global = (function () {  
    return this || (1, eval)('this');  
}());  
Run Code Online (Sandbox Code Playgroud)

即使在严格模式下也会正确评估全局对象.在非严格模式下,值this是全局对象,但在严格模式下是undefined.表达式(1, eval)('this')将始终是全局对象.其原因涉及间接经文的直接规则eval.直接调用eval具有调用者的范围,字符串this将计算为this闭包中的值.间接eval在全局范围内进行评估,就好像它们是在全局范围内的函数内执行一样.由于该函数本身不是严格模式函数,因此将全局对象传入this,然后表达式'this'求值为全局对象.表达式(1, eval)只是强制eval间接并返回全局对象的一种奇特方式.

A1:(1, eval)('this')eval('this')因间接诗歌直接调用的特殊规则不同eval.

A2:原版在严格模式下工作,修改后版本不工作.


Gra*_*hao 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


jfr*_*d00 7

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

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

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

  • 它与ES5严格模式有关.在ES5严格模式下的AFAIK,任何"eval"代码都在其自己的上下文中执行,而不是在全局上下文或封闭上下文中执行.解决这个问题的一种方法是间接引用它作为相关代码. (7认同)