Node JavaScript 上下文共享内置原型?

Pin*_*juh 4 javascript v8 node.js

当创建与节点的一个新的上下文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

(注意:vmmodule是迷宫:vmmodule -> evalsprocess.binding -> node_script.ccsource)

chj*_*hjj 5

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

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

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

但这有一些影响:

vm.runInNewContext('[];') instanceof Array; // returns false
Run Code Online (Sandbox Code Playgroud)

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


Pin*_*juh 5

结论

在 a 中vm.runInNewContext,有两个Object.prototypes:一个是在新上下文中创建的,另一个是通过sandbox. 显然,Node 正确设置了安全令牌,因此允许上下文访问父对象。

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

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

在 node_script.cc:338-345 和 node_script.cc:403-409 中,我看到它正在引用对象,沙箱中的这些对象也是如此,使用父上下文的 Object.prototype 调用 vm.runInNewContext 和在使用不同的 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);
Run Code Online (Sandbox Code Playgroud)

输出:

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]
Run Code Online (Sandbox Code Playgroud)