【JavaScript】ES2026の新機能7選!進化を続ける最新仕様を徹底解説

目次

JavaScript は毎年少しずつ進化しています。その進化の仕組みを担っているのが TC39 という委員会です。TC39 が「完成」と認めた新機能が、年ごとにまとめて ECMAScript(ES) という仕様書に追加されます。2026年版にあたる ES2026 では、これまで「やりたいけど面倒だった」操作を、シンプルに書けるようにする機能が7つ追加されます。難しそうに見えるものもありますが、一つひとつ丁寧に解説しますので、ぜひ最後まで読んでみてください。

ES2026 とは?まず基本を押さえよう

JavaScript には「ECMAScript(ES)」という正式な仕様があります。ES2015(ES6) でアロー関数や constlet が登場したことを覚えている方もいるかもしれません。それ以降も毎年少しずつ機能が追加されており、ES2026 もその流れの一環です。

今回追加される7つの機能は、大きく次のテーマに分けられます。数値を正確に扱うデータの集まり(コレクション)を便利に操作する画像などのバイナリデータを扱いやすくする、そして非同期処理をより簡単に書く、の4つです。それぞれ見ていきましょう。

新機能 詳細解説

1. JSON.parse source text access:巨大な数字を正確に読み取る

JavaScript の数値には「正確に表せる整数の上限」があります。約9000兆(Number.MAX_SAFE_INTEGER)を超える数値になると、JavaScript が自動的に丸めてしまい、元の数字とは異なる値になってしまいます。

たとえば、API からとても大きな ID(会員番号や注文番号など)が返ってきたとき、これまでは精度が失われるという問題がありました。ES2026 ではその元の文字列(sourceを取り出せるようになり、精度を保ったまま扱えます。

const json = '{"id": 100000000000000000000000000000001}';

// 従来:数字として読み込むと末尾の桁が変わってしまう
const old = JSON.parse(json);
console.log(old.id); // 100000000000000000000000000000000(1 が消える!)

// ES2026:reviver の第3引数 context.source で元の文字列を参照できる
const result = JSON.parse(json, (key, val, context) => {
  // 安全に表せる整数の範囲を超えていたら BigInt に変換
  if (typeof val === "number" && !Number.isSafeInteger(val)) {
    return BigInt(context.source);
  }
  return val;
});
console.log(result.id); // 100000000000000000000000000000001n(正確!)

BigInt は末尾に n が付く「とても大きな整数を扱う型」です。Number では表しきれない数値を正確に保持できます。

2. Map.prototype.getOrInsert:「なければ追加、あればそのまま」を1行で

Map はキーと値のペアを管理するデータ構造です。「あるキーが存在しなければ初期値をセットして返す、存在すれば今の値をそのまま返す」という操作は非常によく使うパターンですが、これまでは複数行書く必要がありました。

// 従来:3行かかっていた
const map = new Map();
if (!map.has("apple")) {
  map.set("apple", 0);
}
map.get("apple"); // 0

// ES2026:getOrInsert で1行に!
map.getOrInsert("apple", 0); // なければ 0 をセットして返す
map.getOrInsert("apple", 99); // すでにあるので 0 のまま(上書きされない)
console.log(map.get("apple")); // 0

// 実用例:単語の出現回数を数える
const words = ["apple", "banana", "apple", "cherry", "banana", "apple"];
const counter = new Map();
for (const word of words) {
  // なければ 0 を入れて、その値に +1
  counter.set(word, counter.getOrInsert(word, 0) + 1);
}
console.log(counter.get("apple")); // 3

3. Math.sumPrecise:浮動小数点の「情報落ち」を防ぐ合計計算

浮動小数点数の計算には「情報落ち」という現象があります。たとえば [1e20, 1, -1e20](1京+1−1京)を足すと、答えは 1 のはずですが、通常の計算では 0 になってしまいます。

これは「とても大きな数」と「とても小さな数」を足した際に、小さい方の数が無視されてしまう現象です。Math.sumPrecise はこの問題を解消してくれます。

const values = [1e20, 1, -1e20];

// 通常の合計:情報落ちで 0 になる
values.reduce((a, b) => a + b, 0); // 0(間違い!)

// Math.sumPrecise:正確に計算してくれる
Math.sumPrecise(values); // 1(正しい!)

// ただし、0.1 + 0.2 のような「丸め誤差」は解決しない
// これは JavaScript の数値の仕組みによるもので、別の問題
Math.sumPrecise([0.1, 0.2]); // 0.30000000000000004

「情報落ち」と「丸め誤差」は別の問題です。Math.sumPrecise は前者を解決しますが、後者(0.1 + 0.2 ≠ 0.3 の問題)は引き続き発生します。

4. Error.isError:本物のエラーかどうかを確実に判定する

JavaScript でエラーかどうかを調べるには instanceof Error がよく使われますが、この方法には「偽造できてしまう」という弱点がありました。Error.isError は内部的な仕組みを使って判定するため、偽造を見抜くことができます。

// 偽のエラーオブジェクトを作る(本来は避けるべき操作)
const fakeError = { message: "偽物" };
Object.setPrototypeOf(fakeError, Error.prototype);

// instanceof は騙される
console.log(fakeError instanceof Error); // true(本物に見えてしまう)

// Error.isError は見抜ける
console.log(Error.isError(fakeError));        // false(本物ではないと判定)
console.log(Error.isError(new Error("本物"))); // true

// 実用例:catch したものがエラーかどうかを確実に確認する
try {
  riskyOperation();
} catch (e) {
  if (Error.isError(e)) {
    console.log("エラーが発生しました:", e.message);
  }
}

5. Iterator.concat:複数のリストをまとめて順番に処理する

「イテレータ」とは、要素を1つずつ順番に取り出せるオブジェクトのことです。配列もイテレータの一種です。Iterator.concat を使うと、複数のリストを1つにまとめて順番に処理できます。

スプレッド構文([...a, ...b])との違いは、Iterator.concat必要になるまで要素を生成しない(遅延評価)ため、大量データを扱うときにメモリの節約になります。

const fruits = Iterator.from(["apple", "banana"]);
const veggies = Iterator.from(["carrot", "daikon"]);

// 複数のリストをつなげる
const all = Iterator.concat(fruits, ["grape"], veggies);
console.log([...all]); // ["apple", "banana", "grape", "carrot", "daikon"]

// 実用例:ページ1・2・3のデータをまとめて処理
const combined = Iterator.concat(page1, page2, page3);
for (const item of combined) {
  console.log(item.name);
}

6. Uint8Array to/from Base64 & Hex:画像などのバイナリデータを簡単に変換

画像や音声などのファイルは、コンピュータの中では「0と1の並び(バイナリデータ)」として保存されています。これをテキストとして送受信できる形式に変換するのが Base64Hex(16進数) です。

これまではこの変換に複雑なコードが必要でしたが、ES2026 では Uint8Array(バイナリデータを扱う配列の一種)に変換メソッドが直接追加されます。

// "Hello" を表すバイナリデータ
const arr = new Uint8Array([72, 101, 108, 108, 111]);

// Base64 に変換(テキストとして送信できる形式)
const base64 = arr.toBase64();
console.log(base64); // "SGVsbG8="

// Base64 から元のバイナリデータに戻す
const restored = Uint8Array.fromBase64(base64);
console.log(restored); // Uint8Array [72, 101, 108, 108, 111]

// Hex(16進数)に変換
const hex = arr.toHex();
console.log(hex); // "48656c6c6f"

// Hex から元に戻す
const fromHex = Uint8Array.fromHex(hex);

7. Array.fromAsync:非同期で生成されるデータを配列にまとめる

Array.from は配列やリストを新しい配列に変換するメソッドです。しかし、データが少しずつ届く「非同期の流れ(非同期イテレータ)」には対応していませんでした。Array.fromAsync はそれを解決します。

たとえば、APIから1件ずつデータが届くような場面で、すべて受け取ってから配列にまとめたいときに使えます。

// 1つずつ非同期に値を返すジェネレータ(API から順番にデータが届くイメージ)
async function* asyncGen(n) {
  for (let i = 0; i < n; i++) {
    yield i * 2; // 0, 2, 4, 6 を順番に返す
  }
}

// 従来:for await...of で1つずつ push する必要があった
const old = [];
for await (const item of asyncGen(4)) {
  old.push(item);
}
// [0, 2, 4, 6]

// ES2026:Array.fromAsync で1行に!
const arr = await Array.fromAsync(asyncGen(4));
console.log(arr); // [0, 2, 4, 6]

// 第2引数でそれぞれの値を変換することもできる
const mapped = await Array.fromAsync(asyncGen(4), x => x + 1);
console.log(mapped); // [1, 3, 5, 7]
エンジニア

Math.sumPrecise は「情報落ち」という普段意識しにくいバグを防いでくれる機能です。特に大量の数値を集計する処理を書くときは、reduce の代わりに使うだけで信頼性が上がりますよ。

デザイナー

Uint8Array の Base64 変換、Canvas で描いた画像をそのまま toBase64() で文字列にできるのはありがたいです。今まで調べながら書いていたコードが、ずっとシンプルになりますね。

今すぐ使えるの?サポート状況について

ES2026 の機能は仕様として確定していますが、使っているブラウザや Node.js のバージョンによってはまだ動かない場合があります。実際に使う前に Can I use などで確認するのがおすすめです。また、古い環境でも動かしたい場合は ポリフィル(新機能を古い環境でも動くように補完するコード)を使う方法もあります。

まとめ

ES2026 の7つの新機能を振り返りましょう。どれも「これまで面倒だったことを、標準機能でスッキリ書けるようにする」という共通のコンセプトを持っています。

  • JSON.parse source text access:巨大な数値を含む JSON を精度を失わずにパースできる。
  • Map.getOrInsert:「なければ追加、あればそのまま」を1メソッドで書ける。
  • Math.sumPrecise:大きな数と小さな数が混在する合計計算で情報落ちを防げる(丸め誤差は別問題)。
  • Error.isError:本物のエラーオブジェクトかどうかを確実に判定できる。
  • Iterator.concat:複数のリストを効率よくまとめて順番に処理できる。
  • Uint8Array の Base64 / Hex 対応:画像などのバイナリデータをライブラリなしに変換できる。
  • Array.fromAsync:非同期で届くデータをシンプルに配列にまとめられる。

一度にすべて覚える必要はありません。「こんな機能があったな」と頭の片隅に置いておいて、実際のコードで「面倒だな」と感じた瞬間に思い出してもらえると、きっと役に立つはずです。

コメントを残す

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。