节点JavaScript上下文共享内置原型?

时间:2011-05-03 20:18:38

标签: javascript node.js v8

使用节点vm.runInNewContext创建新上下文时,内置(ObjectFunction等)原型是否共享?

runInNewContext上的文档说:

  

运行code无权访问本地范围,对象sandbox将用作code的全局对象。

Object.prototype是否在全局范围内,因此未共享?

node_script.cc:338-345node_script.cc:403-409我看到它是引用对象,所以这些对象来自sandbox,使用的是Object.prototype父上下文使用不同的vm.runInNewContext

调用Object.prototype和在新上下文中创建的对象

(注意:vm模块是一个迷宫:vm模块 - > evals process.binding - > node_script.cc来源)

2 个答案:

答案 0 :(得分:4)

据我所知,代码是在一个全新的上下文中运行的,具有Object,Array等不同的全局构造函数。

Object.prototype.a = function() { console.log('hello'); };
({}).a(); // 'hello'
require('vm').runInNewContext('({}).a();'); // should throw

如果Object :: a可以访问原始上下文中的变量,我认为它不会真正成为新的上下文。

这有一些含义:

vm.runInNewContext('[];') instanceof Array; // returns false

因为该数组是使用完全不同的构造函数创建的,所以instanceof运算符将受到影响。

答案 1 :(得分:4)

结论

vm.runInNewContext内,有两个Object.prototype:一个在新上下文中创建,另一个通过sandbox引用父上下文。显然,Node已正确设置安全性令牌,因此允许上下文访问父对象。

  

Object.prototype是否在全局范围内,因此未共享?

它不在全球范围内,而是在上下文中。它不是共享的。

  

在node_script.cc:338-345和node_script.cc:403-409中,我看到它引用了这些对象,所以这些对象来自沙箱,使用调用vm.runInNewContext和对象的父上下文的Object.prototype。使用不同的Object.prototype在新上下文中创建?

  

使用Node的vm.runInNewContext创建新上下文时,内置(对象,函数等)原型是否共享?

不共享。

测试

// Test

var vm = require('vm');

var parentLog = function(message) {
    process.stdout.write(message + "\n");
}

Object.prototype.test = "[parent Object.prototype.test]";

var parentObject = new String("[parent parentObject]");

var parentSandbox = {
    log: parentLog,
    testObject: parentObject,
};

var parentCode =
    "log('vm testObject: ' + testObject);" +
    "log('vm testObject.test: ' + testObject.test);" +
    "log('vm create Object.prototype.test');" +
    "Object.prototype.test = '[vm Object.prototype.test]';" +
    "log('vm Object.prototype.test: ' + Object.prototype.test);" +
    "log('vm testObject.test: ' + testObject.test);";

parentLog('pre-parent parentObject: ' + parentObject);
parentLog('pre-parent parentObject.test: ' + parentObject.test);
parentLog('pre-parent Object.prototype: ' + Object.prototype.test);

var parentScript = vm.createScript(parentCode, "<test>");
parentScript.runInNewContext(parentSandbox);

parentLog('post-parent parentObject: ' + parentObject);
parentLog('post-parent parentObject.test: ' + parentObject.test);
parentLog('post-parent Object.prototype: ' + Object.prototype.test);

输出:

pre-parent parentObject: [parent parentObject]
pre-parent parentObject.test: [parent Object.prototype.test]
pre-parent Object.prototype: [parent Object.prototype.test]
vm testObject: [parent parentObject]
vm testObject.test: [parent Object.prototype.test]
vm create Object.prototype.test
vm Object.prototype.test: [vm Object.prototype.test]
vm testObject.test: [parent Object.prototype.test]
post-parent parentObject: [parent parentObject]
post-parent parentObject.test: [parent Object.prototype.test]
post-parent Object.prototype: [parent Object.prototype.test]