What’s New in ECMAScript? A Deep Dive into Stage 4 and Stage 1 Proposals
This article reviews recent TC39 proposals that have reached Stage 4 or entered Stage 1, covering resizable ArrayBuffers, RegExp.escape, joint iteration, iterator sequencing, locale extensions, negated operators, and stable formatting, and explains their impact on the upcoming ECMAScript releases.
Stage 3 → Stage 4
When a proposal reaches Stage 4, it can be trialed in multiple browsers and Node.js, has passed compliance tests, and will be incorporated into the next annual ECMAScript release (e.g., ECMAScript 2023).
Resizable and growable ArrayBuffers
Proposal link: tc39/proposal-resizablearraybuffer . The proposal adds an optional maxByteLength argument to the constructors of ArrayBuffer and SharedArrayBuffer, enabling memory that can grow in place without costly copying.
Example:
let rab = new ArrayBuffer(1024, { maxByteLength: 1024 ** 2 });
assert(rab.byteLength === 1024);
assert(rab.maxByteLength === 1024 ** 2);
assert(rab.resizable);
rab.resize(rab.byteLength * 2);
assert(rab.byteLength === 1024 * 2);
let ab = rab.transfer(1024); // rab is now detached
assert(rab.byteLength === 0);
assert(rab.maxByteLength === 0);
assert(!ab.resizable);
assert(ab.byteLength === 1024);For SharedArrayBuffer a grow(newByteLength) method is added, but shrinking is not allowed.
Stage 1 → Stage 2
At Stage 2 a proposal has a drafted design and may be used for experimental implementations.
RegExp escape
Proposal link: tc39/proposal-regex-escaping . It introduces RegExp.escape to safely escape all characters that have special meaning in regular expressions, handling multi‑code‑unit Unicode characters.
RegExp.escape("The Quick Brown Fox"); // "The Quick Brown Fox"
RegExp.escape("Buy it. use it. break it. fix it."); // "Buy it\. use it\. break it\. fix it\."
RegExp.escape("(*.*)"); // "\(\*\.\*\)"
RegExp.escape("😊 *_* +_+ ... 👍"); // "😊 \*_\* \+_\+ \.\.\. 👍"Joint Iteration
Proposal link: proposal-joint-iteration . It adds native Array.prototype.zip and zipLongest methods so that multiple iterators can be combined element‑wise, similar to Python’s zip.
import { of, zip, map } from 'rxjs';
const age$ = of(27, 25, 29);
const name$ = of('Foo', 'Bar', 'Beer');
const isDev$ = of(true, true, false);
zip(age$, name$, isDev$).pipe(
map(([age, name, isDev]) => ({ age, name, isDev }))
).subscribe(x => console.log(x));Iterator Sequencing
Proposal link: proposal-iterator-sequencing . It creates a new iterator that yields values from several source iterators in sequence.
let lows = Iterator.from([0,1,2,3]);
let highs = Iterator.from([6,7,8,9]);
let lowsAndHighs = function* () {
yield* lows;
yield* highs;
}();
Array.from(lowsAndHighs); // [0,1,2,3,6,7,8,9]Locale Extensions
Proposal link: locale-extensions . It allows web pages to access user locale preferences such as hour cycle, numbering system, etc., while preserving privacy.
navigator.localeExtensions['numberingSystem']; // "deva"
navigator.localeExtensions['hourCycle']; // "h23"Negated In/Instanceof Operator
Proposal link: proposal-negated-in-instanceof . It adds !in and !instanceof operators to express negated membership and type checks more naturally.
if (prop !in obj) { }
if (ins !instanceof Base) { }Stable Formatting
Proposal link: proposal-stable-formatting . It aims to provide a consistent, locale‑independent formatting API for dates and numbers, either by using a special “null” locale (zxx) or by adding an options argument to existing methods.
Summary
New ECMAScript ideas are tracked through TC39’s staged process; the proposals highlighted above illustrate recent advances from Stage 4 to Stage 1, covering memory management, regular‑expression safety, iterator utilities, locale customization, negated operators, and stable formatting.
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.
