Fundamentals 10 min read

What’s New in ECMAScript 2024? A Deep Dive into the Latest Proposals

The ECMAScript 2024 specification, approved on June 26, introduces six major proposals—including well‑formed Unicode strings, asynchronous atomic wait, a powerful RegExp v flag, ArrayBuffer transfer, native array grouping, and Promise.withResolvers—each illustrated with code examples and practical implications for JavaScript developers.

Full-Stack Cultivation Path
Full-Stack Cultivation Path
Full-Stack Cultivation Path
What’s New in ECMAScript 2024? A Deep Dive into the Latest Proposals

ECMAScript 2024 (https://tc39.es/ecma262/2024/) was approved on June 26. The following proposals were incorporated into the final language specification.

Well‑Formed Unicode Strings

JavaScript strings are sequences of UTF‑16 code units (65 536 possible values). Characters outside the Basic Multilingual Plane are represented as surrogate pairs. An isolated surrogate makes a string malformed. The proposal adds String.prototype.isWellFormed() to test for well‑formedness and String.prototype.toWellFormed() to replace isolated surrogates with the replacement character U+FFFD.

'a'.length               // 1
'a'.split('')             // ['a']
'🥑'.length               // 2
'🥑'.split('')            // ['\ud83e', '\udd51'] // surrogate pair
'\ud83e\udd51'.isWellFormed() // true
'\ud83e'.isWellFormed()        // false
'\ud83e'.toWellFormed()        // �
Proposal address: https://github.com/tc39/proposal-well-formed-string

Asynchronous Atomic Wait

Workers provide multithreading in JavaScript via SharedArrayBuffer. The synchronous Atomics.wait() cannot be used on the main thread. The new Atomics.waitAsync() method allows waiting without blocking the main thread.

// main thread
let i32a = null;
const w = new Worker("worker.js");
w.onmessage = function (env) { i32a = env.data };
setTimeout(() => {
  Atomics.store(i32a, 0, 1);
  Atomics.notify(i32a, 0);
}, 1000);
// worker thread
const sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
const i32a = new Int32Array(sab);
postMessage(i32a);
const wait = Atomics.waitAsync(i32a, 0, 0);
// wait may be { async: false, value: "not-equal" | "timed-out" }
// or { async: true, value: Promise<"ok" | "timed-out"> }
if (wait.async) {
  wait.value.then(v => console.log(v));
} else {
  console.log(wait.value);
}
Proposal address: https://github.com/tc39/proposal-atomics-wait-async

RegExp v Flag with Set Notation and String Properties

The v flag extends the 2015 u flag with Unicode property checks, set‑notation operations (subtraction --, intersection &&, union), and a literal string syntax \q. It cannot be combined with u.

const pattern = /./vu; // SyntaxError: invalid flags

Unicode property checks: /\p{Math}/u – matches mathematical symbols /\p{Dash}/u – matches dash punctuation /\p{ASCII_Hex_Digit}/u – matches hexadecimal digits

const patternMath = /\p{Math}/u;
patternMath.test('+'); // true
patternMath.test('z'); // false

Set operations and literal strings:

const pattern = /[\p{RGI_Emoji}--\q{💩}]/v;
pattern.test('😜'); // true
pattern.test('💩'); // false

Example of intersecting uppercase letters with hexadecimal digits:

const pattern = /[\p{Uppercase}&&\p{ASCII_Hex_Digit}]/v;
pattern.test('f'); // true
pattern.test('F'); // false
Proposal address: https://github.com/tc39/proposal-regexp-v-flag

ArrayBuffer Transfer

The proposal adds ArrayBuffer.prototype.transfer() and ArrayBuffer.prototype.transferToFixedLength() to move byte data between locations. A new detached getter reports whether a buffer has been transferred.

const buffer = new ArrayBuffer();
buffer.detached; // false
const newBuffer = buffer.transfer();
buffer.detached; // true
Proposal address: https://github.com/tc39/proposal-arraybuffer-transfer

Array Grouping

The familiar groupBy utility from Lodash/Ramda becomes a native static method on Object and Map. The proposal originally considered Array.prototype.groupBy but chose static methods to avoid conflict with existing sugar.

const langs = [
  { name: "Rust", compiled: true, released: 2015 },
  { name: "Go", compiled: true, released: 2009 },
  { name: "JavaScript", compiled: false, released: 1995 },
  { name: "Python", compiled: false, released: 1991 }
];
const callback = ({ compiled }) => compiled ? "compiled" : "interpreted";
const langsByType = Object.groupBy(langs, callback);
console.log({ langsByType });
// { compiled: [{...}, {...}], interpreted: [{...}, {...}] }
Proposal address: https://github.com/tc39/proposal-array-grouping

Promise.withResolvers

The proposal introduces Promise.withResolvers(), which returns an object containing a promise and its external resolve and reject functions. This enables patterns where resolution or rejection occurs from multiple places.

function createEventsAggregator(eventsCount) {
  const events = [];
  const { promise, resolve, reject } = Promise.withResolvers();
  return {
    add: (event) => {
      if (events.length < eventsCount) events.push(event);
      if (events.length === eventsCount) resolve(events);
    },
    abort: () => reject("Events aggregation aborted."),
    events: promise
  };
}
const eventsAggregator = createEventsAggregator(3);
eventsAggregator.events
  .then(events => console.log("Resolved:", events))
  .catch(reason => console.error("Rejected:", reason));
eventsAggregator.add("event-one");
eventsAggregator.add("event-two");
eventsAggregator.add("event-three");
// Resolved: ["event-one", "event-two", "event-three"]
Proposal address: https://github.com/tc39/proposal-promise-with-resolvers
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptPromise.withResolversECMAScript 2024Array groupingArrayBuffer transferAsync Atomic WaitRegExp v flagWell-Formed Unicode Strings
Full-Stack Cultivation Path
Written by

Full-Stack Cultivation Path

Focused on sharing practical tech content about TypeScript, Vue 3, front-end architecture, and source code analysis.

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.