eval
一、认识
eval()
函数会将传入的字符串当做 JavaScript
代码进行执行。
二、语法
const result = eval(string)
-
string
: 一个表示JavaScript
表达式、语句或一系列语句的字符串。表达式可以包含变量与已存在对象的属性。 -
result
: 返回字符串中代码的返回值。如果返回值为空,则返回undefined
三、场景
四、eval VS new Function()
eval()
: eval
中的代码执行时的作用域为 当前作用域, 如果找不到, 在从 作用链 中的上一层寻找。eval
是一个危险的函数, 它使用与调用者相同的权限执行代码。如果你用 eval()
运行的字符串代码被恶意方(不怀好意的人)修改,您最终可能会在您的网页/扩展程序的权限下,在用户计算机上运行恶意代码。更重要的是,第三方代码可以看到某一个 eval()
被调用时的作用域,这也有可能导致一些不同方式的攻击。eval()
通常比其他替代方法更慢,因为它必须调用 JS
解释器,而许多其他结构则可被现代 JS
引擎进行优化。现代 JavaScript
解释器将 JavaScript
转换为机器代码。这意味着任何变量命名的概念都会被删除。因此,任意一个 eval
的使用都会强制浏览器进行冗长的变量名称查找,以确定变量在机器代码中的位置并设置其值。另外,新内容将会通过 eval()
引进给变量,比如更改该变量的类型,因此会强制浏览器重新执行所有已经生成的机器代码以进行补偿。
var x = 'gloabl scope';
function foo() {
var x = 'local scope';
eval('console.log(x)'); // local scope
}
foo();
new Function()
: new Function()
中的代码执行时的作用域为 全局作用域。无论在哪个地方调用, 它访问的是全局变量, 因此 new Function()
不能访问当前环境的变量,但是可以访问全局变量,安全性更高。 new Function()
要比 eval()
函数的执行速度快得多, new Function()
不会强制浏览器重新执行所有已经生成的机器代码进行补偿, 也不会强制浏览器进行冗长的变量名查找。new Function()
仅需要处理传入的字符串一次,后面重复执行都是同一个函数,而 eval
需要每次都处理,性能更高
var x = 'gloabl scope';
function foo() {
var x = 'local scope';
new Function('console.log(x)')(); // global scope
}
foo();
注意: 虽然这段代码可以在浏览器中正常运行,但在 Node.js
中 foo()
会产生一个“找不到变量 x
的 ReferenceError
。这是因为在 Node
中顶级作用域不是全局作用域,而 x
其实是在当前模块的作用域之中。