node/lib/internal/console/global.js
Joyee Cheung 7851af051a
lib: create global console properties at snapshot build time
It is safe to create the console properties for the global
console at snapshot build time. Streams must still be created
lazily however because they need special synchronization for
the handles.

PR-URL: https://github.com/nodejs/node/pull/51700
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
2024-02-20 18:25:31 +00:00

52 lines
1.8 KiB
JavaScript

'use strict';
// See https://console.spec.whatwg.org/#console-namespace
// > For historical web-compatibility reasons, the namespace object
// > for console must have as its [[Prototype]] an empty object,
// > created as if by ObjectCreate(%ObjectPrototype%),
// > instead of %ObjectPrototype%.
// Since in Node.js, the Console constructor has been exposed through
// require('console'), we need to keep the Console constructor but
// we cannot actually use `new Console` to construct the global console.
// Therefore, the console.Console.prototype is not
// in the global console prototype chain anymore.
const {
FunctionPrototypeBind,
ReflectDefineProperty,
ReflectGetOwnPropertyDescriptor,
ReflectOwnKeys,
} = primordials;
const {
Console,
kBindProperties,
} = require('internal/console/constructor');
const globalConsole = { __proto__: {} };
// Since Console is not on the prototype chain of the global console,
// the symbol properties on Console.prototype have to be looked up from
// the global console itself. In addition, we need to make the global
// console a namespace by binding the console methods directly onto
// the global console with the receiver fixed.
for (const prop of ReflectOwnKeys(Console.prototype)) {
if (prop === 'constructor') { continue; }
const desc = ReflectGetOwnPropertyDescriptor(Console.prototype, prop);
if (typeof desc.value === 'function') { // fix the receiver
const name = desc.value.name;
desc.value = FunctionPrototypeBind(desc.value, globalConsole);
ReflectDefineProperty(desc.value, 'name', { __proto__: null, value: name });
}
ReflectDefineProperty(globalConsole, prop, desc);
}
globalConsole[kBindProperties](true, 'auto');
// This is a legacy feature - the Console constructor is exposed on
// the global console instance.
globalConsole.Console = Console;
module.exports = globalConsole;