Files
scriptc/tests/corpus/7187-namespace-object-reflection.js
T
Chris Tate e1358fb563 Read Math, JSON and Reflect as real objects in JavaScript
In JavaScript sources, Math, JSON or Reflect read as a value lowered to
an identity token, the string "[builtin Math]": typeof, String, `in`,
descriptors and member calls through an alias all had string semantics.

Each of these namespaces read as a value is now one object per program,
built on first use, with Node 24's own properties in Node's order:
function members are writable, configurable and non-enumerable with
Node's `length`, the Math constants are read-only, and
Symbol.toStringTag names the namespace. Members hold the same function
values the spelled member read gives; a member without one throws its
fence when called. Global reads, globalThis, destructuring and
shorthand properties all produce the same object, and an object with a
string Symbol.toStringTag coerces to "[object <tag>]".

Direct member calls keep their static lowerings, so replacing or
deleting a function member would not reach them: such changes throw
SC1090. New properties and attribute-only redefinitions behave as in
Node.
2026-10-23 10:16:30 -05:00

24 lines
1.2 KiB
JavaScript

// Reflection over the namespace objects answers Node's property
// attributes: members are own, non-enumerable properties, the Math
// constants are read-only, and Symbol.toStringTag names the namespace.
function show(object, key) {
const d = Object.getOwnPropertyDescriptor(object, key);
if (d === undefined) return `${String(key)}: none`;
const value = typeof d.value === "function" ? `fn/${d.value.length}/${d.value.name}` : String(d.value);
return `${String(key)}: ${value} ${d.writable} ${d.enumerable} ${d.configurable}`;
}
function inspect(object) {
return [
Object.hasOwn(object, "parse"),
Object.hasOwn(object, "abs"),
Object.keys(object).length,
Object.getOwnPropertyNames(object).length,
].join(" ");
}
console.log(show(Math, "abs"), "|", show(Math, "PI"), "|", show(Math, "max"));
console.log(show(Math, Symbol.toStringTag), "|", show(JSON, "stringify"), "|", show(Reflect, "apply"));
console.log(inspect(Math), "|", inspect(JSON), "|", inspect(Reflect));
console.log(Object.getOwnPropertyNames(JSON).join(","));
console.log(Object.getOwnPropertyNames(Math).slice(0, 5).join(","), Object.getOwnPropertyNames(Math).at(-1));
console.log(Object.prototype.hasOwnProperty.call(Math, "random"), Object.keys(Reflect).length);