Skip to content

EventEmitter subclass: Object.getPrototypeOf(Sub.prototype) !== EventEmitter.prototype #10599

Description

@proggeramlug

Split out from #10556 while fixing new Sub() instanceof EventEmitter (PR #10592, root cause and
fix there). instanceof for a native-builtin subclass now walks the registered class-chain parent
edge, but the subclass's declared prototype object is still not identity-linked to the builtin's real
.prototype object.

Reproduction

import { EventEmitter } from "node:events";
class Sub extends EventEmitter {}
console.log(Object.getPrototypeOf(Sub.prototype) === EventEmitter.prototype);
console.log(typeof EventEmitter.prototype);

Expected (Node 26.5.1)

true
object

Actual (Perry, v0.5.1592 + PR #10592)

false
object

typeof EventEmitter.prototype does not throw and reads as "object", matching Node — so this is
narrower than "accessing EventEmitter.prototype throws"; it is specifically that
Object.getPrototypeOf(Sub.prototype) does not return the same object identity as
EventEmitter.prototype. instanceof, util.inherits-based prototype linking, and the class-chain
walk (all fixed by #10592) do not depend on this identity and are unaffected.

Suspected area

Native-base-class subclassing (see CLAUDE.md "Known-weak areas: Native base-class subclassing" — a
native base's surface is installed at super() time and its parent edge lives in the class registry,
which is a different mechanism than declared-class prototype-object identity). Likely needs
Sub.prototype's [[Prototype]] to be set to the actual EventEmitter.prototype object at class
construction time for natively-backed builtins, not just a reserved class id for the instanceof
chain walk.

Impact

Low — spec-compliance gap for prototype introspection / mixin patterns that compare
Object.getPrototypeOf identity directly, rather than using instanceof. Not currently known to break
a specific npm package.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    package-auditFound by the 2026 package audit: compiling real npm packages from source instead of native bindings

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions