[Effective JavaScript 笔记]第17条:间接调用eval函数优于直接调用
eval函数不仅仅是一个函数。大多数函数只访问定义它们所在的作用域,而不能访问除此之外的作用域(词法作用域)。
eval函数具有访问调用它时的整个作用域的能力。
编译器编写者首次设法优化js时,eval函数很难高效地调用任何一个函数,因为一旦调用的函数是eval函数,那么每个函数调用都需要确保在运行时整个作用域对eval函数是可访问的。
语言标准演化出辨别两种不同的调用eval的方法。
第一种方式:函数调用涉及eval标识符,被认为是一种“直接”调用eval函数的方式。编译器需要确保被执行的程序具有完全访问调用者局部作用域的权限。
例如:
其它方式:其它调用eval函数的方式被叫做“间接”。
两种方式eval函数的参数是在全局作用域内进行求值。
例如:绑定eval函数到另一个变量名,通过该变量名调用函数会使代码失去对所有局部作用域的访问能力。
直接调用eval函数的确切的定义取决于ECMAScript标准相当特殊的规范语言。唯一能够产生直接调用eval函数的语法是可能被(许多的)括号包裹的名称为eval的变量。编写间接调用eval函数的一种简洁方式是使用表达式序列运算符(,)和一个明显毫无意义的数字字面量。
(0,eval)(src);
这是如何工作的呢?
数字字面量0被求值但其值被直接忽略,括号表示的序列表达式产生的结果是eval函数。因此,(0,eval)的行为几乎与简单的eval函数标识符完全一致,一个重要的区别在于整个调用表达式被视为一种间接调用eval函数的方式。
直接调用eval函数的能力很容易被滥用。
对一个来自网络的源字符串进行求值,可能会暴露其内部细节给一些未受信者。
直接调用eval函数导致其包含的函数以及所有直到程序最外层的函数运行相当缓慢的风险。
除非有一个检查局部作用域的特别能力的明确需求,否则应当使用更不容易滥用、更廉价的间接调用eval函数的方式。
提示
将eval函数同一个毫无意义的字面量包裹在序列表达式中以达到强制使用间接调用eval函数的目的
尽可能间接调用eval函数,而不要直接调用eval函数。
[Effective JavaScript 笔记]第17条:间接调用eval函数优于直接调用的更多相关文章
- [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法
js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...
- [Effective JavaScript 笔记]第38条:在子类的构造函数中调用父类的构造函数
示例 场景类 场景图(scene)是在可视化的过程中(如游戏或图形仿真场景)描述一个场景的对象集合.一个简单的场景包含了在该场景中的所有对象(称角色),以及所有角色的预加载图像数据集,还包含一个底层图 ...
- [Effective JavaScript 笔记]第52条:数组字面量优于数组构造函数
js的优雅很大程序要归功于程序中常见的构造块(Object,Function及Array)的简明的字面量语法.字面量是一种表示数组的优雅方法. var a=[1,2,3,5,7,8]; 也可以使用构造 ...
- [Effective JavaScript 笔记] 第14条:当心命名函数表达式笨拙的作用域
js函数会根据上下文改变其含义. function double(x){return x*2;} 这是一个函数声明,也可以是一个命名函数表达式(named function expression),取 ...
- [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码
函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...
- [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象
js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...
- [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符
“1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...
- [Effective JavaScript 笔记]第16条:避免使用eval创建局部变量
js中的eval函数是一个强大.灵活的工具.强大的工具容易被滥用,所以了解是值得的.(本人只用过它来处理json数据).错误使用eval函数的方式一:允许它干扰作用域.调用eval函数会将其参数作为j ...
- [Effective JavaScript 笔记]第67条:绝不要同步地调用异步的回调函数
设想有downloadAsync函数的一种变种,它持有一个缓存(实现为一个Dict)来避免多次下载同一个文件.在文件已经被缓存的情况下,立即调用回调函数是最优选择. var cache=new Dic ...
随机推荐
- 老爷车IE8如何兼容图标字体
前言 首先这个标题再详细的说就是如何解决font-face在IE8下间歇性出现图标字体渲染失败的解决方案. 如果你还不知道什么是图标字体,可以先阅读:链接1,链接2,链接3 先看在IE8下的问题: 而 ...
- ionic 设置logo 与 设置 启动页
1.在项目的根目录下创建resources文件夹. 2.在文件夹中都放入icon.png(应用图标,最小192x192px,不带圆角),splash.png(启动屏幕,最小2208x2208px,中间 ...
- Object C学习笔记26-文件管理(二)
上一篇简单的介绍了如何获取文件属性,删除,拷贝文件等,本文继续记录Object C中文件IO操作. 一. 获取文件的执行主目录 在Object C中提供了一个方法 NSHomeDirectory() ...
- [BZOJ 1483][HNOI 2009]梦幻补丁(有序表启发式合并)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1483 分析: 先将不同的颜色的出现位置从小到大用几条链表串起来,然后统计一下答案 对于 ...
- Web Service 小练习
对于网站与网站之间数据互动,这是我的说法,不是专家说的,不要相信.应该有专业的说法. 从他人的网站通过一个接口获取数据,这一直是我感到神奇的事,怎么实现的,一直萦绕于心,想要弄过究竟,怎么是实现的啊! ...
- Moqui学习之数据与资源
资源位置: 资源门面位置的字符串类似于URL的构成方式:协议,主机,可选端口和文件名.它支持标准的java URL协议(http https ftp jar file).同样也支持一些扩展的协议: c ...
- hdu1247 字典树
开始以为枚举会超时,因为有50000的词.后来试了一发就过了.哈哈.枚举没一个单词,将单词拆为2半,如果2半都出现过,那就是要求的. #include<stdio.h> #include& ...
- ElasticSearch插件安装Head、Kopf与Bigdesk
ElasticSearch-Head ElasticSearch-Head 是一个与Elastic集群(Cluster)相交互的Web前台. ES-Head的主要作用 它展现ES集群的拓扑结构,并且可 ...
- on the way to Peking University
明天就要去北京参加北大夏令营了,希望这次能有所斩获! on the way to Peking University
- 关于bash的shellshock漏洞
这一漏洞的描述如下: Shellshock (CVE-2014-6271, CVE-2014-6277, CVE-2014-6278, CVE-2014-7169, CVE-2014-7186, CV ...