首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在JavaScript中(1,eval)('this') vs eval('this')?

在JavaScript中(1,eval)('this') vs eval('this')?
EN

Stack Overflow用户
提问于 2012-02-02 12:38:00
回答 4查看 20.6K关注 0票数 94

我开始读JavaScript Patterns,一些codes把我搞糊涂了。

代码语言:javascript
复制
var global = (function () {
    return this || (1, eval)('this');
}());

以下是我的问题:

Q1:

(1, eval) === eval

为什么?它是如何工作的?

Q2:为什么不直接

代码语言:javascript
复制
var global = (function () {
    return this || eval('this');
}());

代码语言:javascript
复制
 var global = (function () {
    return this;
}());
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-02-02 12:58:19

(1,eval)和普通的旧式eval之间的区别在于前者是一个值,而后者是一个左值。如果它是其他的标识符,那就更明显了:

代码语言:javascript
复制
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的表达式保证在全局范围内执行。

我仍然不知道的事情:

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

更多信息可以通过here获取。

编辑

显然,我第一个问题的答案是,“几乎总是”。直接eval从当前作用域执行。考虑以下代码:

代码语言:javascript
复制
var x = 'outer';
(function() {
  var x = 'inner';
  eval('console.log("direct call: " + x)'); 
  (1,eval)('console.log("indirect call: " + x)'); 
})();

不出所料(嘿嘿),这打印出来了:

代码语言:javascript
复制
direct call: inner
indirect call: outer

编辑

经过更多的实验后,我暂时说this不能设置为nullundefined。它可以设置为其他错误的值(0、'‘、NaN、false),但只能非常有意地设置。

我要说的是,你的消息来源正在遭受轻微的可逆性颅骨直肠内翻,可能需要考虑花一周的时间在Haskell编程。

票数 116
EN

Stack Overflow用户

发布于 2012-02-02 13:17:18

片段

代码语言:javascript
复制
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:原始版本在严格模式下工作,修改后的版本不能。

票数 35
EN

Stack Overflow用户

发布于 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

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9107240

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档