给一个对象“上下文化”是什么意思?


【What does it mean to "contextify" an object?】

在 Node.js 中执行的所有 JavaScript 都运行在一个“上下文”的范围内。 根据 V8 嵌入指南

【All JavaScript executed within Node.js runs within the scope of a "context". According to the V8 Embedder's Guide:】

在 V8 中,context 是一种执行环境,它允许在单个 V8 实例中运行独立、无关的 JavaScript 应用。你必须明确指定希望运行任何 JavaScript 代码的上下文。

当使用一个对象调用方法 vm.createContext() 时,contextObject 参数将用于封装一个新的 V8 上下文实例的全局对象(如果 contextObjectundefined,则会从当前上下文创建一个新对象,然后再将其上下文化)。这个 V8 上下文为使用 node:vm 模块方法运行的 code 提供了一个隔离的全局环境,在这个环境中代码可以运行。创建 V8 上下文并将其与外部上下文中的 contextObject 关联的过程,就是本文档所称的“将对象上下文化”。

【When the method vm.createContext() is called with an object, the contextObject argument will be used to wrap the global object of a new instance of a V8 Context (if contextObject is undefined, a new object will be created from the current context before its contextified). This V8 Context provides the code run using the node:vm module's methods with an isolated global environment within which it can operate. The process of creating the V8 Context and associating it with the contextObject in the outer context is what this document refers to as "contextifying" the object.】

上下文化会给上下文中的 globalThis 值引入一些特点。例如,它不能被冻结,并且与外部上下文中的 contextObject 在引用上不相等。

【The contextifying would introduce some quirks to the globalThis value in the context. For example, it cannot be frozen, and it is not reference equal to the contextObject in the outer context.】

const vm = require('node:vm');

// An undefined `contextObject` option makes the global object contextified.
const context = vm.createContext();
console.log(vm.runInContext('globalThis', context) === context);  // false
// A contextified global object cannot be frozen.
try {
  vm.runInContext('Object.freeze(globalThis);', context);
} catch (e) {
  console.log(e); // TypeError: Cannot freeze
}
console.log(vm.runInContext('globalThis.foo = 1; foo;', context));  // 1 

要创建一个带有普通全局对象的上下文,并在外部上下文中以更少的怪癖访问全局代理,请将 vm.constants.DONT_CONTEXTIFY 指定为 contextObject 参数。

【To create a context with an ordinary global object and get access to a global proxy in the outer context with fewer quirks, specify vm.constants.DONT_CONTEXTIFY as the contextObject argument.】