mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-08 08:44:37 +08:00
- A named function-local class expression whose only reference to its own
name is a shorthand property (`static wrap() { return { Packed }; }`)
now gets its name binding. The self-reference check read the shorthand
name's property symbol, so the class lowered without the binding and the
property held a placeholder function instead of the class.
- A function-local class's prototype takes its name from the class
object's interned name instead of a registered copy. The registry kept
every such prototype alive until the process exited, so evaluating a
local class repeatedly kept each evaluation's prototype and the method
state it captures: a program that evaluates a local class 200,000 times
and prints each instance peaked at 121 MB, and now at 2 MB.
Reusing a freed object clears its name.
62 lines
1.3 KiB
JavaScript
62 lines
1.3 KiB
JavaScript
// Function-local class expressions in JavaScript whose static members and
|
|
// methods read the class by its own name.
|
|
function point(scale) {
|
|
const P = class Point {
|
|
static origin = new Point(0, 0);
|
|
static unit = Point.scaled(1);
|
|
constructor(x, y) {
|
|
this.x = x;
|
|
this.y = y;
|
|
}
|
|
static scaled(n) {
|
|
return new Point(n * scale, n * scale);
|
|
}
|
|
plus(other) {
|
|
return new Point(this.x + other.x, this.y + other.y);
|
|
}
|
|
};
|
|
return P;
|
|
}
|
|
const P = point(3);
|
|
const sum = P.origin.plus(P.unit).plus(P.unit);
|
|
console.log(sum.x, sum.y, P.unit instanceof P, P.name);
|
|
|
|
function selfName() {
|
|
const K = class Named {
|
|
static who() {
|
|
return Named === this;
|
|
}
|
|
};
|
|
return [K.who(), K.name, typeof K];
|
|
}
|
|
console.log(selfName());
|
|
|
|
function factory(tag) {
|
|
return class Tagged {
|
|
static count = 0;
|
|
constructor() {
|
|
Tagged.count++;
|
|
}
|
|
static make() {
|
|
return new Tagged();
|
|
}
|
|
get tag() {
|
|
return tag + Tagged.count;
|
|
}
|
|
};
|
|
}
|
|
const T = factory("t");
|
|
T.make();
|
|
console.log(T.make().tag, T.count, factory("u").count);
|
|
|
|
// The only reference to the name is a shorthand property.
|
|
function packed() {
|
|
const K = class Packed {
|
|
static wrap() {
|
|
return { Packed };
|
|
}
|
|
};
|
|
return [K.wrap().Packed === K, K.wrap().Packed.name];
|
|
}
|
|
console.log(packed());
|