Fundamentals 16 min read

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.

Alibaba Terminal Technology
Alibaba Terminal Technology
Alibaba Terminal Technology
What New ECMAScript Proposals Just Reached Stage 4 and How They Change JavaScript

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); // false

Stage 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 .

ECMAScriptArrayBufferSymbolTC39AsyncContextStage 4
Alibaba Terminal Technology
Written by

Alibaba Terminal Technology

Official public account of Alibaba Terminal

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.