"contextify" 一个对象是什么意思?


¥What does it mean to "contextify" an object?

在 Node.js 中执行的所有 JavaScript 都在 "context" 的范围内运行。根据 V8 嵌入器指南

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

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

¥In V8, a context is an execution environment that allows separate, unrelated, JavaScript applications to run in a single instance of V8. You must explicitly specify the context in which you want any JavaScript code to be run.

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

¥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.