Fundamentals 23 min read

What New TC39 Proposals Shaped JavaScript in the January 2024 Meeting?

The TC39 January 29 meeting reviewed progress of multiple proposals advancing to later stages—including Intl.DateTimeFormat.formatRange, JSON Modules, Private‑In, Class Static Initializer Block, ResizableArrayBuffer, new Intl APIs, RegExp enhancements, Array findLast, defer import, and several internationalization extensions—detailing requirements, implementations, and upcoming milestones.

Alibaba Terminal Technology
Alibaba Terminal Technology
Alibaba Terminal Technology
What New TC39 Proposals Shaped JavaScript in the January 2024 Meeting?

TC39's January 29 meeting concluded with a review of proposals that achieved stage progress and recent changes.

Stage 3 → Stage 4

Advancing to Stage 4 requires:

Writing test262 tests for all proposal features.

At least two implementations passing the tests and shipping to production.

Submitting a pull request to integrate the proposal into the ECMAScript standard text, signed by an ECMA editor.

Intl.DateTimeFormat.prototype.formatRange

This proposal adds the ability to format date ranges for internationalization. It introduces two methods: Intl.DateTimeFormat.prototype.formatRange – returns a formatted string. Intl.DateTimeFormat.prototype.formatRangeToParts – returns an array of parts.

let date1 = new Date(Date.UTC(2007, 0, 10, 10, 0, 0));
let date2 = new Date(Date.UTC(2007, 0, 10, 11, 0, 0));
let fmt = new Intl.DateTimeFormat("en", { hour: "numeric", minute: "numeric" });
fmt.formatRange(date1, date2); // "10:00 – 11:00 AM"
fmt.formatRangeToParts(date1, date2); // [{type:'hour',value:'10',source:'startRange'}, …]

Available in Chrome 79 and Node.js 12.9.0.

Stage 2 → Stage 3

JSON Modules

The proposal separates JSON Modules from Import Assertions, allowing modules to be imported as JSON with a type assertion.

import json from "./foo.json" assert { type: "json" };
import("foo.json", { assert: { type: "json" } });

Modules must be valid JSON; otherwise, loading fails.

Private Fields In Operator

Introduces the in operator to test for the existence of private fields without triggering exceptions.

class C {
  #brand;
  #method() {}
  static isC(obj) { return #brand in obj && #method in obj; }
}

Stage 1 → Stage 2

Class Static Initializer Block

Allows static blocks inside classes that run during class evaluation and can access private fields.

export class C {
  #x;
  constructor(x) { this.#x = { data: x }; }
  static { getX = obj => obj.#x; }
}
export function readXData(obj) { return getX(obj).data; }

Other Proposals Discussed

ResizableArrayBuffer and GrowableSharedArrayBuffer

New buffer types that support efficient resizing and shared growth.

let rab = new ResizableArrayBuffer(1024, 1024**2);
assert(rab.byteLength === 1024);
rab.resize(rab.byteLength * 2);
assert(rab.byteLength === 2048);

Intl.LocaleInfo

Provides locale‑specific information such as first day of week, weekend range, and text direction.

let zhHans = new Intl.Locale("zh-Hans");
zhHans.weekInfo; // {firstDay:1, weekendStart:6, weekendEnd:7, minimalDays:4}
zhHans.textInfo; // {direction:"ltr"}

Intl.DisplayNames Extension

Expands DisplayNames to include months, weekdays, units, time zones, calendars, and numbering systems.

let dn = new Intl.DisplayNames("zh-Hans", {type:"month", style:"long"});
 dn.of(1); // "1月"

RegExp Set Notation

Adds set operations (intersection, difference) to regular‑expression character classes.

[A--B]   // difference
[A&&B]   // intersection
[\p{Decimal_Number}--[0-9]] // non‑ASCII digits

RegExp.escape

Introduces a utility to escape all RegExp meta‑characters.

RegExp.escape("Buy it. use it. break it. fix it."); // "Buy it\. use it\. break it\. fix it\."

Array.prototype.findLast / findLastIndex

New array methods that search from the end of the array.

const arr = [{value:1},{value:2},{value:3},{value:4}];
arr.findLast(n => n.value % 2 === 1); // {value:3}
arr.findLastIndex(n => n.value % 2 === 1); // 2

Defer Module Import Eval

Syntax to mark import statements as lazily initialized without propagating async/await.

import {x} from "y" with { lazyInit: true };

Extend TimeZoneName Option

Adds additional formatting styles for time‑zone names in Intl.DateTimeFormat.

let options = ["short","long","shortGMT","longGMT","shortWall","longWall"];
options.forEach(name => console.log(new Date().toLocaleTimeString("zh-Hans", {timeZoneName:name})));

EraDisplay

New option to control era formatting (never, always, auto).

new Intl.DateTimeFormat("zh-Hans").format(new Date(-752,3,13)); // "753/4/13" → "公元前 753/4/13 BC"

Intl.LocaleMatcher

Exposes locale‑matching algorithm as a JavaScript API.

Intl.LocaleMatcher.match(["zh-Hans","en"], ["zh","en"], "en"); // "zh"

The meeting also highlighted the formation of the JavaScript Chinese Interest Group (JSCIG), which aims to represent Chinese developers in TC39 discussions and promote ECMAScript improvements.

https://github.com/JSCIG/es-discuss/discussions
TC39 meeting image
TC39 meeting image
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.

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