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函数优于直接调用的更多相关文章

  1. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  2. [Effective JavaScript 笔记]第38条:在子类的构造函数中调用父类的构造函数

    示例 场景类 场景图(scene)是在可视化的过程中(如游戏或图形仿真场景)描述一个场景的对象集合.一个简单的场景包含了在该场景中的所有对象(称角色),以及所有角色的预加载图像数据集,还包含一个底层图 ...

  3. [Effective JavaScript 笔记]第52条:数组字面量优于数组构造函数

    js的优雅很大程序要归功于程序中常见的构造块(Object,Function及Array)的简明的字面量语法.字面量是一种表示数组的优雅方法. var a=[1,2,3,5,7,8]; 也可以使用构造 ...

  4. [Effective JavaScript 笔记] 第14条:当心命名函数表达式笨拙的作用域

    js函数会根据上下文改变其含义. function double(x){return x*2;} 这是一个函数声明,也可以是一个命名函数表达式(named function expression),取 ...

  5. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  6. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  7. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  8. [Effective JavaScript 笔记]第16条:避免使用eval创建局部变量

    js中的eval函数是一个强大.灵活的工具.强大的工具容易被滥用,所以了解是值得的.(本人只用过它来处理json数据).错误使用eval函数的方式一:允许它干扰作用域.调用eval函数会将其参数作为j ...

  9. [Effective JavaScript 笔记]第67条:绝不要同步地调用异步的回调函数

    设想有downloadAsync函数的一种变种,它持有一个缓存(实现为一个Dict)来避免多次下载同一个文件.在文件已经被缓存的情况下,立即调用回调函数是最优选择. var cache=new Dic ...

随机推荐

  1. 【MyEclipse 2015】 逆向破解实录系列【2】(纯研究)

    声明 My Eclipse 2015 程序版权为Genuitec, L.L.C所有. My Eclipse 2015 的注册码.激活码等授权为Genuitec, L.L.C及其付费用户所有. 本文只从 ...

  2. Spring学习进阶(一)初识Spring

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  3. 页面无法访问 css文件加载问题

    1.青奥项目的web配置: 后缀为.html和.vm的请求会被控制器拦截.  控制器没设置目标资源,所以无法访问到资源! 2.文件不能放在vm文件夹下,因为设置了视图解析,vm文件夹下的文件只有后缀为 ...

  4. Ibatis的类型处理器TypeHandler解析

    Ibatis允许用户像在hibernate中一样定义自己的类型,但是,用户自定义类型需要与数据库中的字段类型进行对应.它的处理方法是允许我们扩展TypeHandler.Ibatis框架在处理该数据类型 ...

  5. iOS边练边学--Http网络再学习,简单介绍

    一.URL 什么是URL URL中常见的协议 二.Http Http的基本通信过程 发送Http请求的方法 GET 和 POST 对比 GET 和 POST 的选择 三.iOS中的Http学习 iOS ...

  6. 【HDU 2577】How to Type

    题意 (我做了这题才知道caps lock 锁定大小写后,按一下shift键可以输入相反的大小写.) 这题就是给你只有大小写字母的字符串,求最少多少次按键盘.最后caps lock 必须是关闭的. 分 ...

  7. 蝙蝠算法-python实现

    BAIndividual.py import numpy as np import ObjFunction class BAIndividual: ''' individual of bat algo ...

  8. 洛谷P1417 烹调方案

    题目背景 由于你的帮助,火星只遭受了最小的损失.但gw懒得重建家园了,就造了一艘飞船飞向遥远的earth星.不过飞船飞到一半,gw发现了一个很严重的问题:肚子饿了~ gw还是会做饭的,于是拿出了储藏的 ...

  9. make xconfig时,出现“Unable to find any QT installation"错误

    在make menuconfig的时候,提示是找不到libncurses,最后其实是找不到libncurses-dev,又因为debian系统装的是libncurses5,所以装了libncurses ...

  10. Android APK反编译问题

    因为这几天想做一个离线音乐播放器,然后需要很多.png图片,在度娘上搜图片感觉效果不好, 就需要用到反编译工具来将一些.apk文件中的资源文件提取出来. 这里就只讲下怎么使用工具来进行反编译,什么?你 ...