Frontend Development 13 min read

What New ECMAScript Proposals Will Shape JavaScript in 2023?

This article reviews the latest Stage 4 ECMAScript proposals—including ArrayBuffer transfer, iterator helpers, RegExp modifiers, import attributes, Promise.try, duplicate named capture groups, and Set methods—explaining their purpose, syntax, and example usage for modern JavaScript development.

Taobao Frontend Technology
Taobao Frontend Technology
Taobao Frontend Technology
What New ECMAScript Proposals Will Shape JavaScript in 2023?

When a proposal reaches Stage 4, it means it can be tried in multiple browsers and Node.js, and it will be incorporated into the next annual ECMAScript release such as ECMAScript 2023.

ArrayBuffer transfer

Proposal address: proposal-arraybuffer-transfer

This proposal adds two new methods to the

ArrayBuffer

prototype:

ArrayBuffer.transfer

and

ArrayBuffer.transferToFixedLength

, providing the ability to transfer buffer ownership.

When we need to read/write a buffer, external writes must be prevented:

<code>function validateAndWrite(arrayBuffer) {
  // Do some asynchronous validation.
  await validate(arrayBuffer);

  // Assuming we have reached here, it's valid; write it to disk.
  await fs.writeFile("data.bin", arrayBuffer);
}

const data = new Uint8Array([0x01, 0x02, 0x03]);
validateAndWrite(data.buffer);
setTimeout(() => {
  data[0] = data[1] = data[2] = 0x00;
}, 50);
</code>

Because the execution time of

validate(arrayBuffer)

may cause the buffer content to expire, a defensive approach copies the buffer before validation:

<code>function validateAndWriteSafeButSlow(arrayBuffer) {
  // Copy first!
  const copy = arrayBuffer.slice();

  await validate(copy);
  await fs.writeFile("data.bin", copy);
}
</code>

However, this traditional method can be slow. Using

transfer

enables zero‑copy ownership transfer for better performance:

<code>function validateAndWriteSafeAndFast(arrayBuffer) {
  // Transfer to take ownership, which implementations can choose to implement as a zero-copy move.
  const owned = arrayBuffer.transfer();

  // arrayBuffer is detached after this point.
  assert(arrayBuffer.detached);

  await validate(owned);
  await fs.writeFile("data.bin", owned);
}
</code>

Sync Iterator Helpers

Proposal address: proposal-iterator-helpers

This proposal adds convenient methods to iterator objects, such as

map

,

filter

,

flatMap

,

reduce

,

forEach

, and

some

, plus several RxJS‑like helpers.

.take(limit)

Limits the number of generated elements and returns a new iterator.

<code>function* naturals() {
  let i = 0;
  while (true) {
    yield i;
    i += 1;
  }
}

const result = naturals()
  .take(3);
result.next(); // {value: 0, done: false}
result.next(); // {value: 1, done: false}
result.next(); // {value: 2, done: false}
result.next(); // {value: undefined, done: true}
</code>

.drop(limit)

Skips the specified number of elements and returns a new iterator.

<code>function* naturals() {
  let i = 0;
  while (true) {
    yield i;
    i += 1;
  }
}

const result = naturals()
  .drop(3);
result.next(); // {value: 3, done: false}
result.next(); // {value: 4, done: false}
result.next(); // {value: 5, done: false}
</code>

.flatMap(mapperFn)

Expands or flattens nested structures and returns a new iterator.

<code>const sunny = ["It's Sunny in", "", "California"].values();

const result = sunny
  .flatMap(value => value.split(" ").values());
result.next(); // {value: "It's", done: false}
result.next(); // {value: "Sunny", done: false}
result.next(); // {value: "in", done: false}
result.next(); // {value: "", done: false}
result.next(); // {value: "California", done: false}
result.next(); // {value: undefined, done: true}
</code>

.toArray()

Converts the values produced by an iterator into an array.

<code>function* naturals() {
  let i = 0;
  while (true) {
    yield i;
    i += 1;
  }
}

const result = naturals()
  .take(5)
  .toArray();

result // [0, 1, 2, 3, 4]
</code>

RegExp Modifiers

Most regex engines (Perl, PCRE, .NET, Oniguruma) allow controlling flags inside sub‑expressions, but ECMAScript lacks this capability. This proposal introduces regex pattern modifiers to flexibly control flags such as

i

(ignore case),

m

(multiline),

s

(dot‑all), and

x

(extended).

Modifier syntax:

(?imsx-imsx:subexpression)

– set or unset the listed flags for the subexpression.

(?imsx-imsx)

– set or unset flags from the current position to the next

)

or end of pattern.

<code>const re1 = /^[a-z](?-i:[a-z] "a-z")$/i;
re1.test("ab"); // true
re1.test("Ab"); // true
re1.test("aB"); // false

const re2 = /^(?i:[a-z])[a-z]$/;
re2.test("ab"); // true
re2.test("Ab"); // true
re2.test("aB"); // false
</code>

Import Attributes and JSON Modules

Proposal address: proposal-import-attributes

This proposal adds inline syntax to import statements so that additional information can be passed with the module specifier, enabling generic support for new module types.

Example for importing a JSON module:

<code>// static import
import json from "./foo.json" with { type: "json" };
// dynamic import
import("foo.json", { with: { type: "json" } });
</code>

The proposal also supports inline syntax for re‑exports:

<code>export { val } from './foo.js' with { type: "javascript" };
</code>

Different host environments (Node.js, web) provide various ways to load modules; import attributes can convey these differences, even in HTML via script tag attributes.

<code>&lt;script src="foo.wasm" type="module" withtype="webassembly"&gt;&lt;/script&gt;
</code>

Promise.try

Proposal address: proposal-promise-try

While

.catch

handles errors in a Promise chain, the initial synchronous call (e.g.,

queryUser(id)

) is not captured. The

Promise.try

method wraps the starting call in a resolved Promise, extending error handling to synchronous failures.

<code>import pTry from 'p-try';

function processUser(id) {
  return pTry(queryUser, id)
    .then(user => queryAccount(user))
    .then(account => queryAuth(account))
    .catch(() => { /* ... */ });
}
</code>

Duplicate Named Capture Groups

Proposal address: proposal-duplicated-named-capturing-groups

Current ECMAScript requires capture group names to be unique, preventing their use in alternations such as

YYYY‑MM‑DD|DD‑MM‑YYYY

. This proposal allows non‑unique names to enable such patterns.

Set Methods

Proposal address: proposal-set-methods

This proposal adds a suite of built‑in methods to

Set

for common set operations:

intersection

,

union

,

difference

,

symmetricDifference

,

isSubsetOf

,

isSupersetOf

, and

isDisjointFrom

. Each method accepts another

Set

(or an object implementing

.size

,

.keys

, and

.has

).

References

proposal-arraybuffer-transfer: https://github.com/tc39/proposal-arraybuffer-transfer

proposal-iterator-helpers: https://github.com/tc39/proposal-iterator-helpers

Regular Expression X Mode: https://github.com/rbuckton/proposal-regexp-x-mode

proposal-import-attributes: https://github.com/tc39/proposal-import-attributes

proposal-promise-try: https://github.com/tc39/proposal-promise-try

p-try: https://www.npmjs.com/package/p-try

proposal-duplicate-named-capturing-groups: https://github.com/tc39/proposal-duplicate-named-capturing-groups

proposal-set-methods: https://github.com/tc39/proposal-set-methods

javascriptECMAScriptIteratorPromiseArrayBufferSetRegExpProposals
Taobao Frontend Technology
Written by

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.

0 followers
Reader feedback

How this landed with the community

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