編集

ECMAScript 2025 が正式承認

Ecma International の第 129 回総会で ECMAScript 2025 言語仕様が正式に承認され、標準となった。編集者は Shu-yu Guo、Michael Ficarra、Kevin Gibbons が担当。

ECMAScript 2025 の新機能、Import attributes と JSON modules、Iterator helper methods、Set の集合演算メソッド、RegExp.escape()、正規表現パターン修飾子、Duplicate named capturing groups、Promise.try()、16 ビット浮動小数点数サポートなど。

出展:Ecma International approves new standards - Ecma International

#Import attributes と JSON modules

JavaScript 以外のアーティファクトをインポートするための構文基盤が追加された。最初にサポートされるのは JSON モジュール。静的インポートではwith { type: 'json' }構文を使用し、動的インポートでは第二引数にオプションオブジェクトを渡す。withの後のオブジェクトリテラル構文でインポート属性を指定する。

js
// 設定ファイルのインポート
import settings from './app-settings.json' with { type: 'json' };

// 動的にJSONを読み込み
const userPrefs = await import('./user-preferences.json', {
  with: { type: 'json' }
});

console.log(settings.theme); // "dark"
console.log(userPrefs.default.language); // "ja"

#Iterator helper methods

イテレータをより活用できるヘルパーメソッドが追加された。配列メソッドと同名のfilter()map()flatMap()some()every()find()reduce()forEach()に加え、イテレータ固有のdrop()take()toArray()が利用可能。

配列メソッドに対する改善点として、任意のイテラブルデータ構造で使用でき、中間配列を作成せずに段階的に計算する。大量データ処理において、配列メソッドが全値に対して順次メソッドを適用するのに対し、イテレータメソッドは各値に対して全メソッドを適用する。

js
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// イテレータを使った効率的な処理
const result = numbers
  .values()
  .filter((n) => n % 2 === 0) // 偶数のみ
  .drop(1) // 最初の1つをスキップ
  .take(2) // 最初の2つを取得
  .map((n) => n * 3) // 3倍にする
  .toArray(); // 配列に変換

console.log(result); // [12, 18]

#Set の集合演算メソッド

Set 同士の集合演算メソッドが追加された。intersection()(積集合)、union()(和集合)、difference()(差集合)、symmetricDifference()(対称差集合)による演算と、isSubsetOf()(部分集合判定)、isSupersetOf()(上位集合判定)、isDisjointFrom()(素集合判定)による関係チェックが可能。

js
const frontendSkills = new Set(["HTML", "CSS", "JavaScript"]);
const backendSkills = new Set(["JavaScript", "Node.js", "Python"]);

// 共通スキル(積集合)
const commonSkills = frontendSkills.intersection(backendSkills);
console.log(commonSkills); // Set { 'JavaScript' }

// 全スキル(和集合)
const allSkills = frontendSkills.union(backendSkills);
console.log(allSkills); // Set { 'HTML', 'CSS', 'JavaScript', 'Node.js', 'Python' }

// フロントエンド専用スキル(差集合)
const frontendOnly = frontendSkills.difference(backendSkills);
console.log(frontendOnly); // Set { 'HTML', 'CSS' }

#RegExp.escape()

正規表現内でテキストを安全に使用するためのエスケープ機能。特殊文字を含むテキストを正規表現パターン内で文字列として扱いたい場合に使用する。引用符で囲まれていないテキストのみを削除するような処理で活用できる。

js
const userInput = "price: $9.99 (tax included)";
const searchTerm = "$9.99";

// 特殊文字を含む文字列を安全にエスケープ
const escapedTerm = RegExp.escape(searchTerm);
const regex = new RegExp(escapedTerm, "g");

const isFound = regex.test(userInput);
console.log(isFound); // true

// 置換処理での活用
const highlighted = userInput.replace(
  new RegExp(RegExp.escape(searchTerm), "g"),
  `<mark>${searchTerm}</mark>`
);
console.log(highlighted); // "price: <mark>$9.99</mark> (tax included)"

#正規表現パターン修飾子

正規表現の一部分にのみフラグを適用できるインラインフラグ機能。正規表現全体ではなく、特定の部分にのみ大文字小文字を無視するiフラグなどを適用できる。(?i:pattern)のような構文で使用する。

js
const text = "Visit our STORE or browse the catalog";

// 特定の単語のみ大文字小文字を無視
const pattern = /visit.*(?i:store).*catalog/;
console.log(pattern.test(text)); // true

// 複数の修飾子を組み合わせ
const emailPattern = /^[a-z]+@(?i:GMAIL|YAHOO)\.com$/;
console.log(emailPattern.test("user@GMAIL.com")); // true
console.log(emailPattern.test("USER@gmail.com")); // false(ユーザー名は小文字のみ)

// 部分的にマルチライン対応
const multiPattern = /start(?m:^middle$)end/;

#Duplicate named capturing groups

異なる選択肢内であれば同じグループ名を複数回使用できるようになった。正規表現の異なる分岐で同じ名前のキャプチャグループを定義し、マッチした分岐のグループ結果を取得できる。

js
// 日付フォーマットの解析(同じグループ名を異なる選択肢で使用)
const datePattern =
  /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})|(?<day>\d{2})\/(?<month>\d{2})\/(?<year>\d{4})/v;

const isoDate = "2025-06-27";
const usDate = "27/06/2025";

const isoMatch = datePattern.exec(isoDate);
console.log(isoMatch.groups); // { year: "2025", month: "06", day: "27" }

const usMatch = datePattern.exec(usDate);
console.log(usMatch.groups); // { year: "2025", month: "06", day: "27" }

// どちらの形式でも同じグループ名でアクセス可能
console.log(isoMatch.groups.year); // "2025"
console.log(usMatch.groups.year); // "2025"

#Promise.try()

純粋に非同期でないコードで Promise チェーンを開始できる機能。同期関数が例外を投げる可能性がある場合でも、Promise チェーン内で統一的にエラーハンドリングできる。

js
function parseUserData(jsonString) {
  // JSON.parseは同期関数だが例外を投げる可能性がある
  return Promise.try(() => {
    const data = JSON.parse(jsonString);
    return validateUser(data); // 非同期のバリデーション関数
  })
    .then((user) => {
      console.log("Valid user:", user);
      return user;
    })
    .catch((error) => {
      console.error("Parse or validation error:", error);
      return null;
    });
}

// 使用例
parseUserData('{"name": "Alice", "age": 30}').then((result) =>
  console.log(result)
);

parseUserData("invalid json").then((result) => console.log(result)); // null(エラーがキャッチされる)

#16 ビット浮動小数点数サポート

半精度浮動小数点数の処理機能が追加された。Math.f16round()メソッド、新しい型付き配列Float16ArrayDataViewgetFloat16()setFloat16()メソッドが提供される。

js
// 16ビット浮動小数点数への丸め
const originalValue = 3.141592653589793;
const float16Value = Math.f16round(originalValue);
console.log(float16Value); // 3.140625(16ビット精度に丸められる)

// Float16Arrayの使用
const float16Array = new Float16Array([1.5, 2.7, 3.9]);
console.log(float16Array); // Float16Array(3) [ 1.5, 2.69921875, 3.900390625 ]

// DataViewでの16ビット浮動小数点数操作
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);

view.setFloat16(0, 42.5);
view.setFloat16(2, -17.25);

console.log(view.getFloat16(0)); // 42.5
console.log(view.getFloat16(2)); // -17.25

// メモリ効率的なグラフィックスデータ処理に有用
const vertices = new Float16Array([0.0, 1.0, 0.5, -0.5, -0.5, -0.5]);
編集