Skip to content

Repeated evaluation of a non-capturing class declaration returns the same class object #11759

Closed

Description

@proggeramlug

A class declaration with no captures that is evaluated more than once yields the same class object each time. Node creates a fresh class on every evaluation.

function f() { class K {} return K; }
console.log(f() === f());            // node: false   perry: true
const a = f(), b = f();
(a.prototype as any).x = 1;
console.log((new b() as any).x);     // node: undefined   perry: 1

The same happens for a non-capturing class declared in a loop body at module top level. Classes that capture variables are already fresh per evaluation, which is why the fixture in #11758 uses capturing classes for these cases.

Fixing this changes how classes inside bundle wrapper functions are compiled: CJS and esbuild bundles declare classes in functions that usually run once. So before changing the default, it needs a real-code census (tsc, Zod, the corpus) of how many repeated class evaluations actually happen and what per-evaluation class creation costs.

Found while fixing #11758.

Activity

  1. proggeramlug commented on Oct 3, 2026

    @proggeramlug
    ContributorAuthor

    Partial progress: #11780 landed (fresh class objects: extends the evaluated class, own their members, stringify to source). Merged unverified at the owner's request; the full gates and cost A/B are still to run. Leaving open.

  2. added 2 commits that reference this issue on Oct 4, 2026
    d75c4e9
    288c016
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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions