eval()
、new Function()
(高级)eval()
new Function()
在本章中,我们将介绍两种动态评估代码的方法:eval()
和 new Function()
。
eval()
给定一个包含 JavaScript 代码的字符串 str
,eval(str)
会评估该代码并返回结果。
> eval('2 ** 4')16
调用 eval()
有两种方式:
“不通过函数调用”指的是“任何看起来不像 eval(···)
的东西”。
eval.call(undefined, '···')
(使用 函数的 .call()
方法)eval?.()
()(使用 可选链)(0, eval)('···')
(使用 逗号运算符)globalThis.eval('···')
const e = eval; e('···')
以下代码说明了区别:
.myVariable = 'global';
globalThisfunction func() {
const myVariable = 'local';
// Direct eval
.equal(eval('myVariable'), 'local');
assert
// Indirect eval
.equal(eval.call(undefined, 'myVariable'), 'global');
assert }
在全局上下文中评估代码更安全,因为代码可以访问的内部结构更少。
new Function()
new Function()
创建一个函数对象,并按如下方式调用:
const func = new Function('«param_1»', ···, '«param_n»', '«func_body»');
上一条语句等价于下一条语句。请注意,«param_1»
等不再位于字符串字面量中。
const func = function («param_1», ···, «param_n») {
«func_body»; }
在下一个示例中,我们创建了两次相同的函数,第一次通过 new Function()
,第二次通过函数表达式。
const times1 = new Function('a', 'b', 'return a * b');
const times2 = function (a, b) { return a * b };
尽可能避免动态评估代码。
很多时候,JavaScript 本身就足够动态,因此您不需要 eval()
或类似的东西。在以下示例中,我们使用 eval()
(A 行)所做的事情在没有它的情况下也可以实现(B 行)。
const obj = {a: 1, b: 2};
const propKey = 'b';
.equal(eval('obj.' + propKey), 2); // (A)
assert.equal(obj[propKey], 2); // (B) assert
如果您必须动态评估代码:
new Function()
而不是 eval()
:它始终在全局上下文中执行其代码,并且函数为评估的代码提供了一个干净的接口。eval
而不是直接 eval
:在全局上下文中评估代码更安全。