新function和虚拟机有什么区别?

我想知道新函数 (效果 – 评估 )和vm模块之间有什么区别。

从表面上看,这些看起来是相似的:

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

但是,一个简单的基准testing显示vmnew Function之间的性能差异非常显着。 因此,我假设每一种操作都有一个根本的区别。

我想了解不同之处,以便作出一个受过教育的决定何时使用哪个工具。


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

这里有一些代码来显示一些区别:

 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可以访问全局和局部variables
  • new Function可以访问全局variables,但是没有局部variables
  • vm.runInThisContext()可以像new Function一样访问
  • vm.runInNewContext()甚至不能访问像console这样的全局variables

vmfunction有一些额外的function,如能够通过超时限制代码的运行时间。

从安全angular度来看, vm.runInNewContext()是最受限制的。 它甚至不允许require()没有显式地通过沙盒对象传递给require函数。