【转载】(0, eval)(‘this’)
var window = this || (0, eval)('this')
在avalon源码中有这么一行代码,var window = this很容易理解
这里复习一下Global Object:
Global Object代表一个全局对象,js中不允许存在独立的函数,变量和常量,它们都是Global Object 的属性和方法,包括内置的属性和方法
但是Global Object实际并不存在,它是由window充当这个角色,并且这个过程是在js首次加载时进行的
在一个页面中,首次载入js代码时会创建一个全局执行环境,这个全局执行环境的作用域链实际上只有一个对象,即全局对象(window),并用this来引用全局对象。
那么,(0, eval)(‘this’)是什么?有什么用呢?什么情况下会执行呢?
(0, eval)('this')
- 先从语法上来解读:
这里用了逗号操作符,逗号操作符总会返回表达式中的最后一项,所以0在这里基本上没有什么用,换成其他任意数值均可
然后通过”()”来立即执行这个表达式,返回eval
为eval传入’this’字符串,然后被当做实际的ECMAScript语句来解析
- 这个表达式的作用:
因为在严格模式下,匿名函数中的this为undefined
为了防止在严格模式下window变量被赋予undefined,使用(0, eval)(‘this’)就可以把this重新指向window对象
- 原理??
(0, eval)??这个执行完以后是什么呢?
答案是eval
那么和eval(“this”)就没有区别了呀,那么
又怎么解释呢?
===========================================================
这里要提出一个间接eval调用和直接eval调用的概念
- 间接eval调用:
(1, eval)('...')
(eval, eval)('...')
(1 ? eval : 0)('...')
(__ = eval)('...')
var e = eval; e('...')
(function(e) { e('...') })(eval)
(function(e) { return e })(eval)('...')
(function() { arguments[0]('...') })(eval)
this.eval('...')
this['eval']('...')
[eval][0]('...')
eval.call(this, '...')
eval('eval')('...') - 直接eval调用:
eval('...')
(eval)('...')
(((eval)))('...')
(function() { return eval('...') })()
eval('eval("...")')
(function(eval) { return eval('...'); })(eval)
with({ eval: eval }) eval('...')
with(window) eval('...')看了以上这些例子就可以明白了,(0, eval)(‘this’)是间接的eval调用,那么直接和间接调用之后的区别是什么呢?
eval(); // <-- 调用括号左边的表达式 — "eval" — 计算出一个引用
(eval)(); // <-- 调用括号左边的表达式 — "(eval)" — 计算出一个引用
(((eval)))(); // <-- 调用括号左边的表达式 — "(((eval)))" — 计算出一个引用
(1,eval)(); // <-- 调用括号左边的表达式 — "(1, eval)" — 计算出一个值
(eval = eval)(); // <-- 调用括号左边的表达式 — "(eval = eval)" — 计算出一个值可以看出,间接调用计算出来的是一个值,而不是引用
如ECMAScript所说,这是因为两个操作符 - (例子(1,eval)里的)逗号操作符和(例子(eval=eval)里的)等号操作符-对它的操作数执行了GetValue。因此,(1,eval)和(eval = eval)计算出一个值,而eval 和 (eval)计算出的是一个引用。
且间接调用是在全局范围内执行执行代码的。

就像你所看到的,第一个调用,是一个直接调用,方法中的this值是obj的引用(返回"obj.foo"),第二个调用,通过逗号表达式对它的操作数执行了GetValue,让this的值指向了全局对象
讲到这里,再回来看看(0, eval)('this'),是不是就不难理解,其实这里的this就是指向全局对象
这样在es5的严格模式下,也能获得全局对象的引用,而不是undefined了更多EVAL的详细内容可以在这里找到:http://www.oschina.net/translate/global-eval-what-are-the-options
- 这里补充一点:
严格模式下,外部访问不到eval()中创建的任何变量或函数,为eval赋值也会导致错误

- 参考文章:
global-eval-what-are-the-options
indirect-function-call-in-javascript
----------------------------------------------
原文的博客地址:http://vico.me/ 似乎作者正在对博客进行改版,很多文章都找不到了,幸好这篇文章我在半年前前看的时候存了下来。
【转载】(0, eval)(‘this’)的更多相关文章
- (0,eval)('this')与eval的区别
看doT源码的时候,看到了这么一句代码: global = (function(){ return this || (0,eval)('this'); }()); global.doT = doT; ...
- Global eval. What are the options?
David Flanagan最近写了一个关于全局eval的简单表达式,可以用一行式子表示: var geval = this.execScript || eval; 尽管看起来很简短,但是跨浏览器的兼 ...
- [Effective JavaScript 笔记]第17条:间接调用eval函数优于直接调用
eval函数不仅仅是一个函数.大多数函数只访问定义它们所在的作用域,而不能访问除此之外的作用域(词法作用域).eval函数具有访问调用它时的整个作用域的能力.编译器编写者首次设法优化js时,eval函 ...
- C# eval()函数浅谈
<%# Bind("Subject") %> //绑定字段 <%# Container.DataItemIndex + 1%> //实现自动编号<%# ...
- ASP.NET Eval四种绑定方式
1.1.x中的数据绑定语法 <asp:Literal id="litEval2" runat="server" Text='<%#DataBinde ...
- [转载] FFmpeg API 变更记录
最近一两年内FFmpeg项目发展的速度很快,本来是一件好事.但是随之而来的问题就是其API(接口函数)一直在发生变动.这么一来基于旧一点版本的FFmpeg的程序的代码在最新的类库上可能就跑不通了. 例 ...
- 网站商务通链接快速标识v1.0.js
js代码为: function getSwt(keys){ try{ if(openZoosUrl&&typeof(openZoosUrl)=="function" ...
- 浅谈 js eval作用域
原文:浅谈 js eval作用域 就简单聊下如何全局 eval 一个代码. var x = 1; (function () { eval('var x = 123;'); })(); console. ...
- 全局作用域 eval
eval是在caller的作用域里运行传给它的代码: var x = 'outer'; (function() { var x = 'inner'; eval('x'); // & ...
随机推荐
- quilt
1 什么是quilt quilt是一个patch管理工具,特别适合于对多个patch进行管理. quilt是基于gnu patch和diff的. 2 使用quilt创建一个patch 第一步,quil ...
- 一个实用的UIView的类别
// // FrameAccessor.h // FrameAccessor // // Created by Alex Denisov on 18.03.12. // Copyright (c) 2 ...
- golang---信号signal
golang中os/signal包的使用 chenbaoke · 2015-06-17 20:03:59 · 2748 次点击 · 预计阅读时间 1 分钟 · 不到1分钟之前 开始浏览 这是一个创建于 ...
- local_irq_disable
local_irq_disable 仅仅是 设置 当前CPU 的中断屏蔽位 disable_irq 是禁用 全部cpu 中断(只是当前irq) 如果你要禁止所有的中断该怎么办? 在2.6内核中,可以通 ...
- uestc 250 windy数(数位dp)
题意:不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? 思路:数位dp #include<iostream ...
- NOSQL安全攻击
摘自:http://www.infoq.com/cn/articles/nosql-injections-analysis JSON查询以及数据格式 PHP编码数组为原生JSON.嗯,数组示例如下: ...
- Identifier expected after this token
Cursor cursor = db.query(true, "user", new String[]{"id","mode"}, &quo ...
- qq截图原理
屏幕截图实现的大体思想是:发起截图时,将当前窗口的图像保存到内存中,然后弹出一个置顶的全屏窗口,将保存的桌面图片绘制到这个全屏窗口上:初始时绘制的是灰化的桌面图像,选择截图区域后,则将选中的区域绘制成 ...
- HDU - 2828 网络流
题目大意 有n个灯,m个开关,由于线路乱接导致可能有多个开关对应一个灯(并联),有的灯在开关开的时候亮 有的灯在开关关的时候亮,[每个开关最多对应两盏灯],试找出一种开关的ON,OFF状态,使得所有灯 ...
- git apply failed (转载)
转自:http://blog.csdn.net/aaronzzq/article/details/6955893 git version 1.6.0.4 几个新手刚刚开始接触 Git,为了维护核心仓库 ...