eval() 函数会将传入的字符串当做 JavaScript 代码进行执行
console.log(eval('2 + 2'));// 4
let p = 1;
let aa = eval('(function a(){console.log("eval定义的函数",p)})()');
console.log(aa);// "eval定义的函数" 1
建议在nodejs模式下执行,浏览器会报安全问题!
入参只有一个,是string类型:
一个表示 JavaScript 表达式、语句或一系列语句的字符串。表达式可以包含变量与已存在对象的属性
new Function 每个 JavaScript 函数实际上都是一个 Function
对象。运行 (function(){}).constructor === Function // true
便可以得到这个结论。
由 Function
构造函数创建的函数不会创建当前环境的闭包,它们总是被创建于全局环境,因此在运行时它们只能访问全局变量和自己的局部变量,不能访问它们被 Function
构造函数创建时所在的作用域的变量。这一点与使用 eval() 执行创建函数的代码不同。
需要在浏览器上运行,在nodejs上运行的结果是不一样的
var x = 10;
function createFunction1() {
var x = 20;
return new Function('return x;'); // 这里的 x 指向最上面全局作用域内的 x
}
var f1 = createFunction1();
console.log(f1());// 10
nodejs中是无法读取到new Function外声明的变量的,因为Node.js 中 f1()
会产生一个“找不到变量 x
”的 ReferenceError
。这是因为在 Node 中顶级作用域不是全局作用域,而 x
其实是在当前模块的作用域之中。
eval和new Function在浏览器上运行时都存在安全风险,因为浏览器无法感知你里面的字符串是否安全!
永远不要使用 eval!底层实现的库一般都是使用new Function的形式
eval()
是一个危险的函数, 它使用与调用者相同的权限执行代码。如果你用 eval()
运行的字符串代码被恶意方(不怀好意的人)修改,您最终可能会在您的网页/扩展程序的权限下,在用户计算机上运行恶意代码。更重要的是,第三方代码可以看到某一个 eval()
被调用时的作用域,这也有可能导致一些不同方式的攻击。相似的 Function 就不容易被攻击。
eval()
通常比其他替代方法更慢,因为它必须调用 JS 解释器,而许多其他结构则可被现代 JS 引擎进行优化。
此外,现代JavaScript解释器将javascript转换为机器代码。 这意味着任何变量命名的概念都会被删除。 因此,任意一个eval的使用都会强制浏览器进行冗长的变量名称查找,以确定变量在机器代码中的位置并设置其值。 另外,新内容将会通过 eval()
引进给变量, 比如更改该变量的类型,因此会强制浏览器重新执行所有已经生成的机器代码以进行补偿。 但是,(谢天谢地)存在一个非常好的eval替代方法:只需使用 window.Function。 这有个例子方便你了解如何将eval()
的使用转变为Function()
。