我想知道new Function(实际上是eval)和vm
模块之间的区别。
从表面上看,这些看似相似:
vm
中的context
并使用Function
构造函数中的parameters)。vm
可以使用runInContext
重复使用多个调用之间的上下文。 new Function
可以使用参数重复使用相同的上下文。但是,简单的基准测试显示vm
和new Function
之间存在非常显着的性能差异。因此,我假设每种方法的运作存在潜在的差异。
我想了解不同之处,以便在何时使用哪种工具做出明智的决定。
我知道有一个类似的问题(Node.JS vm.runInNewContext() vs require() and eval())。但是,这个问题已经讨论了eval
和require
之间的区别。它没有解决eval
和vm
模块之间的区别。
答案 0 :(得分:3)
这里有一些代码可以显示一些差异:
const vm = require('vm');
globalName = 'global';
var localName = 'local';
function code(prefix) {
return `console.log("${prefix}:", typeof globalName, typeof localName)`;
}
eval(code('eval'));
new Function(code('function'))();
vm.runInThisContext(code('vm, this ctx'));
vm.runInNewContext(code('vm, new ctx'));
其输出:
eval: string string
function: string undefined
vm, this ctx: string undefined
evalmachine.<anonymous>:1
console.log("vm, new ctx:", typeof globalName, typeof localName)
^
ReferenceError: console is not defined
所以:
eval
可以访问全局和局部变量new Function
可以访问全局变量,但没有局部变量vm.runInThisContext()
可以访问与new Function
可以vm.runInNewContext()
甚至无法访问console
vm
函数具有一些附加功能,例如能够传递超时以限制代码的运行时。
从安全角度来看,vm.runInNewContext()
是最受限制的。如果没有require()
函数明确地通过沙箱对象传入,它甚至不会允许require
。