What’s New in ECMAScript 2023? Inside the Latest TC39 Proposals and Stage Advancements
The recent TC39 meeting promoted several proposals—including Hashbang Grammar, Duplicate Named Capturing Groups, Import Reflection, Symbol Predicates, Policy Maps and Sets, Function Memoization, and Object.pick/omit—through various stage thresholds, outlining the requirements for each advancement and providing example code for the new language features.
Stage 3 → Stage 4
The Hashbang Grammar proposal reached Stage 4 and will become an official ECMAScript 2023 feature. Earlier proposals such as Duplicate Named Capturing Groups and Import Reflection also progressed, while Function Memoization and Object.pick/omit entered Stage 1 for the first time.
Requirements for advancing from Stage 3 to Stage 4
All proposal content must have corresponding tc39/test262 tests that are merged into the test suite.
At least two implementations must pass the Test 262 suite and ship a released version.
A pull request adding the proposal to the official tc39/ecma262 repository must be opened and approved by the ECMAScript editor.
Hashbang Grammar
Proposal link: proposal-hashbang
Hashbang (or shebang) syntax specifies the interpreter for a script on Unix‑like systems, e.g.:
<code>#!/usr/bin/env node
console.log("ecma");</code>Running a script with Node normally requires
node index.js. By adding a shebang and making the file executable (
chmod +x index.js), the script can be run directly with
./index.js. The
/usr/bin/envprogram locates the
nodeexecutable, avoiding hard‑coded paths.
This proposal ensures that the shebang line is preserved and passed to the JavaScript engine, allowing engines to handle it uniformly.
Stage 2 → Stage 3
Advancing from Stage 2 to Stage 3 requires:
A draft standard text reviewed and signed by designated TC39 members.
Signature of agreement from the ECMAScript editor.
Duplicate Named Capturing Groups
Proposal link: proposal-duplicate-named-capturing-groups
Current regular‑expression syntax forbids using the same name for multiple capturing groups, which prevents matching alternative patterns with shared group names. This proposal relaxes the uniqueness constraint, enabling constructs such as:
<code>const dateRegexp = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})|(?<day>[0-9]{2})-(?<month>[0-9]{2})-(?<year>[0-9]{4})/;</code>Thus, developers can capture the same logical parts from different pattern branches.
Stage 1 → Stage 2
Moving from Stage 1 to Stage 2 requires drafting the full standard text for the proposal.
Import Reflection
Proposal link: proposal-import-reflection
Import Reflection adds a reflection type to the default import name, allowing metadata to be attached to imports. Example syntax:
<code>import module x from "<specifier>";
const x = await import("<specifier>", { reflect: "module" });</code>This enables use‑cases such as specifying additional types for WebAssembly imports, e.g., distinguishing
WebAssembly.Instancefrom
WebAssembly.Module.
Stage 0 → Stage 1
Advancing from Stage 0 to Stage 1 requires:
A TC39 champion to shepherd the proposal.
A clear problem statement, motivation, and high‑level solution.
Concrete examples demonstrating the problem and solution.
Discussion of API shape, algorithms, semantics, and implementation risks.
Symbol Predicates
Proposal link: proposal-symbol-predicates
Introduces two new static methods on the
Symbolobject:
Symbol.isRegistered(sym)– checks if a symbol is globally registered.
Symbol.isWellKnown(sym)– checks if a symbol is a built‑in well‑known symbol such as
Symbol.iteratoror
Symbol.toPrimitive.
These methods help differentiate unique symbols from well‑known ones, especially for use as
WeakMapkeys.
<code>const isUniqueSymbol = sym => typeof sym === "symbol" && !(Symbol.isRegistered(sym) || Symbol.isWellKnown(sym));
isUniqueSymbol(Symbol()); // true
isUniqueSymbol(Symbol.for("foo")); // false
isUniqueSymbol(Symbol.asyncIterator); // false</code>Policy Maps and Sets
Proposal link: proposal-policy-map-set
Defines native cache‑policy data structures for JavaScript, including FIFO, LIFO, LRU, and LFU maps and sets:
<code>new FIFOMap(maxEntries, entries = [])
new FIFOSet(maxValues, values = [])
new LIFOMap(maxEntries, entries = [])
new LIFOSet(maxValues, values = [])
new LRUMap(maxEntries, entries = [])
new LRUSet(maxValues, values = [])
new LFUMap(maxEntries, entries = [])
new LFUSet(maxValues, values = [])</code>These structures implement the usual
Map/
Setmethods but are not subclasses, and their capacity can be limited via the constructor arguments.
Function Memoization
Proposal link: proposal-function-memo
Provides a built‑in way to memoize functions. The proposal adds
Function.prototype.memowhich returns a cached version of the function, and an
@Function.memodecorator that marks a function as memoized:
<code>function f(x) { console.log(x); return x * 2; }
const fMemo = f.memo();
fMemo(3); // logs 3, returns 6
fMemo(3); // returns 6 without logging</code>The memoization can be backed by any custom cache object implementing
.get(),
.has(), and
.set(), making the Policy Maps and Sets proposal a natural fit.
Object.pick / Object.omit
Proposal link: proposal-object-pick-or-omit
Introduces two top‑level methods on
Object:
Object.pick(obj, keysOrPredicate)– extracts specified properties.
Object.omit(obj, keysOrPredicate)– removes specified properties.
They support both an array of keys and a predicate function, similar to Lodash’s
pickByand
omitBy:
<code>Object.pick({a:1, b:2}, v => v === 1); // => {a:1}
Object.omit({name:"Bob", age:30}, ["age"]); // => {name:"Bob"}</code>Conclusion
The JavaScript Chinese Interest Group (JSCIG) invites developers to discuss ECMAScript proposals on GitHub: https://github.com/JSCIG/es-discuss/discussions.
References
tc39/test262: https://github.com/tc39/test262
tc39/ecma262: https://github.com/tc39/ecma262
proposal‑hashbang: https://github.com/tc39/proposal-hashbang
proposal‑duplicate‑named‑capturing‑groups: https://github.com/tc39/proposal-duplicate-named-capturing-groups
proposal‑import‑reflection: https://github.com/tc39/proposal-import-reflection
proposal‑symbol‑predicates: https://github.com/rricard/proposal-symbol-predicates
proposal‑policy‑map‑set: https://github.com/tc39/proposal-policy-map-set
lru‑cache: https://www.npmjs.com/package/lru-cache
quick‑lru: https://www.npmjs.com/package/quick-lru
proposal‑function‑memo: https://github.com/js-choi/proposal-function-memo
proposal‑object‑pick‑or‑omit: https://github.com/tc39/proposal-object-pick-or-omit
Taobao Frontend Technology
The frontend landscape is constantly evolving, with rapid innovations across familiar languages. Like us, your understanding of the frontend is continually refreshed. Join us on Taobao, a vibrant, all‑encompassing platform, to uncover limitless potential.
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.