2016-09-09 85 views
1

我想知道new Function(效果 - eval)和vm模块之间的区别是什么。new Function和vm有什么区别?

表面上,这些似乎是相似的:

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

但是,一个简单的基准测试结果显示,在vmnew Function之间的性能差异非常显着。因此,我假设每种方法都有一个根本区别。

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


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

回答

2

下面是一些代码,以表现出一定的差异:

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()

+0

嗯,看起来像'new Function'可以在node.js中创建局部变量。看看我的问题在这里的答案:https://stackoverflow.com/questions/46440029/how-can-i-dynamically-create-a-variable-dynamically-in-the-current-scope-in​​-java#46440182 –

+2

不,在这个例子中,它是设置一个全局的。通过删除你的''eval''var',全局变得对模块代码中的'a.b'的设置变得明显,并且因此记录到日志中。 –

+0

啊,我看到......可怕 –

相关问题