跳到主要内容

eval

2023年08月02日
柏拉文
越努力,越幸运

一、认识


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.jsfoo() 会产生一个“找不到变量 xReferenceError。这是因为在 Node 中顶级作用域不是全局作用域,而 x 其实是在当前模块的作用域之中。