What New ECMAScript Proposals Just Reached Stage 4 and How They Change JavaScript
This article reviews the latest TC39 proposals that have advanced to Stage 4—including Change Array By Copy, Intl.NumberFormat V3, and Symbol as WeakMap Keys—explains their new immutable‑array methods, international‑number formatting APIs, weak‑map key support, and also highlights proposals moving between other stages such as Async Context and ArrayBuffer transfer.
Stage 3 → Stage 4
When a proposal reaches Stage 4 it can be trialed in browsers and Node.js, has passed compliance tests, and will be incorporated into the next annual ECMAScript release (e.g., ECMAScript 2023).
Change Array By Copy
Proposal link: proposal-change-array-by-copy Traditional array methods like sort, reverse, and splice mutate the original array. This proposal adds a family of methods that perform the same operation but return a new array, preserving the original:
Array.prototype.toReversed (instead of reverse)
Array.prototype.toSorted (instead of sort)
Array.prototype.toSpliced (instead of splice)
Array.prototype.with (instead of copyWithin)
TypedArray prototypes also gain the three methods except toSpliced. These methods originate from the Record and Tuple proposal (Stage 2) and are now a separate proposal to bring immutable‑array capabilities to JavaScript. Polyfills are available via CoreJS and ES Shims.
Intl.NumberFormat V3
Proposal link: proposal-intl-numberformat-v3 This adds new methods to Intl.NumberFormat for easier internationalized number handling, such as formatting ranges, rounding, and splitting strings.
const nf = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "CNY",
maximumFractionDigits: 0,
});
nf.formatRange(3, 5); // "CNY 3–5"Symbol as WeakMap Keys
Proposal link: proposal-symbols-as-weakmap-keys Enables Symbol values to be used as keys in WeakMap, which previously only accepted objects. This helps store Symbol references inside Records and Tuples, which are value‑based data structures.
Unique and well‑known Symbols are allowed as keys; registered Symbols are not, because they cannot be observed for garbage collection.
const weakMap = new WeakMap();
const key = Symbol('ref for data');
const data = {};
weakMap.set(key, data);Stage 2 → Stage 3
Proposals at Stage 3 are being implemented in browsers and Node.js and are only changed for major issues.
ArrayBuffer transfer
Proposal link: proposal-arraybuffer-transfer This adds ArrayBuffer.prototype.transfer to move ownership of an ArrayBuffer without copying its bytes, making large data transfers (e.g., between a main thread and a Web Worker) faster and preventing the original buffer from being mutated.
function validateAndWriteSafeAndFast(arrayBuffer) {
const owned = arrayBuffer.transfer();
assert(arrayBuffer.detached);
await validate(owned);
await fs.writeFile("data.bin", owned);
}Stage 1 → Stage 2
Intl era and monthCode
Proposal link: proposal-intl-era-monthcode Extends the Intl API (ECMAScript 402) to provide richer era and month‑code handling beyond the ISO‑8601 focus of the Temporal proposal.
Symbol predicates
Proposal link: proposal-symbol-predicates Introduces Symbol.isRegistered and Symbol.isWellKnown to detect whether a Symbol is a registered or well‑known Symbol, helping developers avoid using unsupported Symbol types as WeakMap keys.
const isUniqueSymbol = sym =>
typeof sym === "symbol" && !(Symbol.isRegistered(sym) || Symbol.isWellKnown(sym));
isUniqueSymbol(Symbol()); // true
isUniqueSymbol(Symbol.for("foo")); // false
isUniqueSymbol(Symbol.asyncIterator); // falseStage 0 → Stage 1
Async Context
Proposal link: proposal-async-context Provides a standard way to propagate arbitrary values across asynchronous call chains, similar to React Context but for async operations. The API includes static wrap, instance run, and get methods.
class AsyncContext<T> {
static wrap<R>(fn: (...args: any[]) => R): (...args: any[]) => R;
run<R>(value: T, fn: () => R): R;
get(): T;
}Prevent prototype‑chain pollution – Symbol.proto
Proposal link: proposal-symbol-proto Addresses prototype‑pollution vulnerabilities by disallowing string‑based prototype access (e.g., __proto__, prototype) in “safe mode” and introducing dedicated symbols ( Symbol.proto or Symbol.constructor) for controlled prototype manipulation.
Summary
The JavaScript Chinese Interest Group (JSCIG) coordinated these proposals, and discussions continue on GitHub: https://github.com/JSCIG/es-discuss/discussions .
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
