new Function和vm有什么区别?

时间:2016-09-09 17:18:22

标签: node.js

我想知道new Function(实际上是eval)和vm模块之间的区别。

从表面上看,这些看似相似:

  • 两者都可以限制在特定的上下文中(使用vm中的context并使用Function构造函数中的parameters)。
  • vm可以使用runInContext重复使用多个调用之间的上下文。 new Function可以使用参数重复使用相同的上下文。

但是,简单的基准测试显示vmnew Function之间存在非常显着的性能差异。因此,我假设每种方法的运作存在潜在的差异。

我想了解不同之处,以便在何时使用哪种工具做出明智的决定。

我知道有一个类似的问题(Node.JS vm.runInNewContext() vs require() and eval())。但是,这个问题已经讨论了evalrequire之间的区别。它没有解决evalvm模块之间的区别。

1 个答案:

答案 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