ES2025(ECMAScript 2025)の新機能まとめ|JavaScriptに追加された全機能を実例で解説
ES2025(ECMAScript 2025)は、2025年6月25日にEcma Internationalが承認したJavaScriptの言語仕様で、ECMA-262の第16版にあたる。毎年6月に採択される年次版の最新にあたり、TC39が「Stage 4(完成)」まで通した提案がまとめて標準に入った。
この記事では、ES2025で言語本体(ECMA-262)に加わった機能を、実際に動くコードと対応状況つきで一つずつ整理する。Iterator HelpersやSetの新メソッドのように「今日から使える」ものと、Float16ArrayやRegExp.escapeのように対応ランタイムがまだ新しいものを分けて扱う。あわせて、Import Attributesの構文がassertからwithへ変わった点など、古い解説が間違えやすい箇所も明確にする。
まとめ:ES2025で押さえるべき新機能
- Iterator Helpers:イテレーターに
map/filter/take/dropなどが付き、配列に変換せず遅延評価でつなげる。 - 新しいSetメソッド:
intersection/union/differenceなど7つの集合演算がSetに標準搭載。 - Promise.try:同期関数でも非同期関数でも一様にPromiseで包み、投げられた例外を
.catch()で受けられる。 - Import Attributes / JSON Modules:
import x from "./x.json" with { type: "json" }でJSONを直接読み込む。旧assertは非推奨。 - 正規表現の強化:部分適用の
(?i:...)モディファイア、重複した名前付きキャプチャグループ、RegExp.escape()。 - Float16Array:半精度(16bit)浮動小数点の型付き配列と
Math.f16round、DataViewのgetFloat16/setFloat16。
Lazy.jsやIxJSはES2025の機能ではなくサードパーティ製ライブラリなので、この記事では扱わない。以下、標準に入った機能だけを順に見ていく。
ES2025とは:策定時期と機能の全体像
ECMAScriptは2015年のES6(ES2015)で大改訂されて以降、毎年6月に「その年に完成した提案」をまとめて版を切る運用になった。ES2025はその11回目にあたる年次版で、正式名称はECMA-262第16版。「ES6の次の大改訂」を待つのではなく、毎年小さく確定していく点がES2015以前との一番の違いだ。
ES2025で言語本体に入った提案は次のとおり。集合演算や反復処理のように日常コードに効くものが中心で、大きな構文追加は含まれない。
| 機能 | できること |
|---|---|
| Iterator Helpers | イテレーターにmap/filter/take等を追加 |
| 新しいSetメソッド | 和・積・差など7つの集合演算 |
| Promise.try | 同期・非同期を問わず安全にPromise化 |
| Import Attributes | importにwithで属性を付与 |
| JSON Modules | JSONをモジュールとして直接import |
| 正規表現モディファイア | (?i:…)でフラグを部分適用 |
| 重複名前付きグループ | 同名のキャプチャグループを分岐で再利用 |
| RegExp.escape() | 文字列を正規表現に安全に埋める |
| Float16Array | 半精度浮動小数点の型付き配列 |
| eval由来グローバル変数の再宣言 | evalで生成したグローバルvarの重複宣言を許容(細部の仕様修正) |
なお日付書式のIntl.DurationFormatやロケール情報のアクセサ(weekInfoなど)も2025年に確定したが、これらは言語本体(ECMA-262)ではなく国際化仕様(ECMA-402)側の追加で、管轄が異なる。この記事は言語本体の機能を対象とする。
Iterator Helpers:反復処理を配列化せずつなぐ
これまでmapやfilterは配列(Array.prototype)のメソッドだった。ES2025のIterator Helpersは同じ操作をイテレーター自身に持たせる。途中で配列を作らず、必要な分だけ評価してからtoArray()で確定できるため、大きなデータや無限イテレーターを扱うときに無駄な中間配列が出ない。
const result = [1, 2, 3, 4, 5, 6]
.values() // 配列イテレーターを取得
.filter(x => x % 2 === 0)
.map(x => x * 10)
.take(2) // 先頭2件で打ち切り(残りは評価しない)
.toArray();
console.log(result); // [20, 40]
追加されるのはmap/filter/take/drop/flatMap/reduce/toArray/forEach/some/every/findと、任意のイテラブルをラップするIterator.from()。take(2)のように途中で打ち切ると後続の要素は計算されないので、重い変換を全件に流す前に絞り込めるのが実利だ。
ひとつ注意したいのは、ここで標準化されたのは同期イテレーターのヘルパーだけだという点。asyncMapやasyncFilterといった名前のメソッドはES2025には存在せず、非同期イテレーター向けのヘルパーは別提案として検討中の段階にとどまる。非同期を扱いたい場合は、いったん結果を確定してからasync/awaitで非同期処理を組む形になる。
新しいSetメソッド:集合演算が標準で書ける
これまでSet同士の積集合や差集合は、filterとhasを組み合わせて自前で書くしかなかった。ES2025はよく使う集合演算を7つ、Set.prototypeに直接足した。引数はSetに限らず、sizeとhasとkeysを持つ「Setライク」なオブジェクトも受け付ける。
const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);
a.intersection(b); // Set {3, 4} … 積集合
a.union(b); // Set {1, 2, 3, 4, 5, 6} … 和集合
a.difference(b); // Set {1, 2} … 差集合
a.symmetricDifference(b); // Set {1, 2, 5, 6} … 対称差
a.isSubsetOf(b); // false … 部分集合か
a.isSupersetOf(b); // false … 上位集合か
a.isDisjointFrom(b); // false … 共通要素なしか
元のSetは書き換えず、新しいSet(判定系はboolean)を返す。タグの絞り込み、権限の重なり判定、2つのIDリストの突き合わせといった処理を、ライブラリなしで読める形に落とせる。
Promise.try:同期エラーも非同期エラーも同じ経路で拾う
コールバックとして渡された関数が「同期で例外を投げるか、Promiseを返すか」を呼び出し側が知らない、という状況はよくある。同期で投げられた例外は.catch()に届かず、外側のtry/catchで別に受ける必要があった。Promise.tryは関数を即時に実行しつつ、その戻り値も投げられた例外もまとめてPromiseに包む。
// parse が同期例外を投げても、非同期で失敗しても、1つの .catch() で拾える
Promise.try(() => JSON.parse(input))
.then(data => render(data))
.catch(err => showError(err));
Promise.resolve().then(fn)でも似たことはできるが、その場合fnの実行は必ず次のマイクロタスクに回る。Promise.tryはfnを同期的に走らせるので、同期処理の実行タイミングを遅らせずにエラーハンドリングだけ統一できる。引数の受け渡しにも対応し、Promise.try(fn, a, b)のように書ける。
Import AttributesとJSON Modules:assertではなくwith
Import Attributesは、モジュールを読み込むときに「これはどう解釈すべきか」という属性をwithで添える構文だ。最初の用途がJSON Modules、つまりJSONファイルをそのままモジュールとしてimportすることで、fetchやバンドラのローダー設定なしに設定ファイルを読める。
// 静的インポート
import config from "./config.json" with { type: "json" };
console.log(config.apiEndpoint);
// 動的インポート
const { default: settings } = await import("./settings.json", {
with: { type: "json" },
});
ここで最重要なのが構文だ。以前の提案ではassert { type: "json" }(Import Assertions)だったが、これは非推奨となり、ES2025ではwithに置き換わった。名前が変わったのは、この属性が「読み込んだ後に検証するだけ」ではなく「どう読み込むか」を左右するため。実際、with { type: "json" }を付けると、サーバーが実行可能なMIMEタイプを返してもホストはそのファイルをJavaScriptとして実行しないので、セキュリティ上の意味も持つ。新規コードは必ずwithで書き、既存のassertは移行しておきたい。読み込んだJSONの型を安全に扱う設計はJSONの型定義とデータ型の整理とあわせて考えると崩れにくい。
正規表現の3つの強化
ES2025は正規表現に、性格の異なる3つの機能を別々に追加した。読者が探す論点も別なので、それぞれ分けて説明する。なお、よく混同されるd(hasIndices)はES2022、v(unicodeSets)はES2024の機能で、ES2025のものではない。
パターンモディファイア:フラグを一部だけ効かせる
これまでiやm、sのフラグは正規表現全体にしかかけられなかった。ES2025のモディファイアは、(?i:...)で有効化、(?-i:...)で無効化と、パターンの一部にだけフラグを適用できる。使えるのはi・m・sの3つで、gやuなどは対象外だ。
// "hello" の部分だけ大文字小文字を無視する
/(?i:hello) world/.test("HELLO world"); // true
/(?i:hello) world/.test("HELLO WORLD"); // false(world は区別されるため不一致)
重複した名前付きキャプチャグループ
従来は、1つの正規表現の中で同じ名前のキャプチャグループを2回使うと構文エラーだった。日付が「2025-03」と「03/2025」のように複数の書式で来るとき、書式ごとにグループ名を変えるしかなかった。ES2025は、|で分かれた別々の選択肢であれば同名グループを許す。
const re = /(?<year>\d{4})-\d{2}|\d{2}/(?<year>\d{4})/;
"2025-03".match(re).groups.year; // "2025"
"03/2025".match(re).groups.year; // "2025"
どちらの書式でもgroups.yearで同じ名前で取り出せるので、分岐ごとに後処理を分ける必要がなくなる。
RegExp.escape():ユーザー入力を安全に正規表現へ
ユーザーが入力した文字列をそのまま正規表現に埋め込むと、.や*が特殊文字として解釈され、意図しないマッチや例外を招く。RegExp.escape()は、その文字列を正規表現リテラルとして安全に使える形にエスケープした文字列を返す。
const keyword = "1 + 1 = 2.";
const re = new RegExp(RegExp.escape(keyword));
RegExp.escape("Hello. World.");
// "\x48ello\.\x20World\." のような文字列を返す
// 先頭文字とスペースは \xNN 形式、記号はバックスラッシュでエスケープされる
先頭の文字やスペースまで\xNNで包むのは、直前の別のパターンと連結したときに\1のような解釈へ化けないための仕様。見た目は冗長だが、生成した文字列を他のパターンにそのまま差し込んでも壊れない安全側の設計になっている。自前のエスケープ関数を持ち回っていた箇所は、これに置き換えられる。
Float16Array:半精度浮動小数点数の型付き配列
ES2025は16bit(半精度)の浮動小数点を扱うFloat16Arrayを追加した。既存のFloat32Array(32bit)・Float64Array(64bit)に対して、1要素あたり2バイトで済む。精度は落ちるが、メモリ帯域が支配的な用途で効いてくる。
const f16 = new Float16Array([1.5, 2.25, 3.14159]);
f16[2]; // 3.140625(16bit精度に丸められる)
Math.f16round(3.14159); // 3.140625(16bitに丸めた値を返す)
const view = new DataView(new ArrayBuffer(2));
view.setFloat16(0, 1.5);
view.getFloat16(0); // 1.5
半精度はGPU計算(WebGPU)や機械学習の推論のように、値の刻みより「多くの数値を一度に運ぶこと」が重要な場面で使う形式だ。DataViewのgetFloat16/setFloat16が入ったことで、バイナリプロトコルやファイルフォーマットの読み書きでも半精度を素直に扱える。逆に、金額や座標のように精度が要る値には向かないので、用途を選んで使う機能といえる。
対応状況とES2025の始め方
ES2025の機能は、確定した時期や実装の進み方によって使える範囲に差がある。実務では次のように分けて考えるのが安全だ。
| 機能 | 目安 |
|---|---|
| Iterator Helpers / Setメソッド | 現行ブラウザとNode.js 22以降で概ね利用可 |
| Import Attributes / JSON Modules | 現行ブラウザとNode.js 22以降で利用可 |
| 正規表現モディファイア / 重複名前付きグループ | 現行ブラウザで利用可 |
| Promise.try | 2025年前後のランタイムが必要 |
| Float16Array / RegExp.escape | 対応が新しめ(2025年前後のランタイム) |
細かいバージョン番号は各ランタイムのリリースで動くため、本番投入前には必ずMDNの各機能ページとcaniuse(Baseline)で対象環境の対応を確認したい。とくにFloat16ArrayとRegExp.escapeは対応が出そろって日が浅く、古い端末やLTS前のNode.jsが残る環境では避けるか、フォールバックを用意すべきだ。逆にIterator Helpersや新しいSetメソッドは実装が進んでおり、ライブラリ(Lodashなど)で代替していた箇所を素の言語機能へ置き換える判断がしやすい。
まだ対応していない環境も含めて配信したいなら、BabelとcorejsでトランスパイルとポリフィルをかければES2025構文を古い環境向けに変換できる。TypeScriptを使っているなら、tsconfig.jsonのlibにesnext系を含めることでこれらの型が付く。ビルドチェーンの前提を最新版に上げる流れは、TypeScript 6.0の移行の検討ともつながる。
よくある質問
ES2025はいつ正式に決まりましたか?
2025年6月25日にEcma Internationalの総会で承認され、ECMA-262の第16版として公開されました。ECMAScriptは2015年のES2015(ES6)以降、毎年6月に版を切る運用になっており、ES2025はその年次版の最新にあたります。
ES2025とES2024の違いは何ですか?
ES2024には正規表現のvフラグ(unicodeSets)、Array Grouping、Promise.withResolvers、リサイズ可能なArrayBufferなどが入りました。ES2025はそれとは別に、Iterator Helpers、新しいSetメソッド、Promise.try、Import Attributes、正規表現の部分適用モディファイア、Float16Arrayなどを追加しています。どちらも年次版なので、片方がもう片方を置き換えるものではなく積み上げの関係です。
import … assert { type: “json” } はもう使えませんか?
assert構文(Import Assertions)は非推奨になり、ES2025ではwith { type: "json" }に置き換わりました。多くのランタイムは当面assertも警告つきで受け付けますが、新規コードはwithで書き、既存コードも順次移行するのが安全です。
ES2025は今のブラウザでそのまま動きますか?
Iterator HelpersやSetメソッド、Import Attributesなどは現行のブラウザとNode.js 22以降で概ね動きます。一方でFloat16ArrayやRegExp.escape()は対応が新しいため、対象環境によっては動かないことがあります。動作対象を広げたい場合はBabelとcorejsでトランスパイル・ポリフィルをかけてください。
ES6(ES2015)とES2025はどういう関係ですか?
ES2015(ES6)はクラス・アロー関数・モジュールなどを一度に入れた大改訂で、この版を境にECMAScriptは毎年版を切る方式へ移りました。ES2025はES6から数えて11回目の年次版で、ES6以降に積み重ねてきた改善の最新版という位置づけです。