【ES2022〜2024】モダンJavaScriptの新機能まとめ

JavaScriptは毎年新しい仕様が追加されています。

古い書き方のまま開発を続けていると、以下のような場面で非効率なコードを書いてしまうことがあります。

  • 配列の末尾要素を取得する際に arr[arr.length - 1] と書いている
  • 配列をソートするたびに元のデータが書き換わってしまう
  • 配列をカテゴリごとにグループ分けするのに複雑な処理を書いている

ES2022〜ES2024で追加された機能を使うことで、こういった処理をシンプルに書くことができます。

実践

at() ― 配列・文字列の末尾要素を取得する

以下のような配列があるとします。

const arr = [10, 20, 30, 40, 50];

at() を使うと末尾からの要素取得をシンプルに書けます。

console.log(arr.at(-1)); // 50
console.log(arr.at(-2)); // 40

従来の書き方と比較すると以下のようになります。

// 従来の書き方
console.log(arr[arr.length - 1]); // 50

// at() を使った書き方
console.log(arr.at(-1)); // 50

toSorted() / toReversed() ― 元の配列を変えずに操作する

以下のような配列があるとします。

const original = [3, 1, 4, 1, 5];

従来の sort() は元の配列を書き換えてしまいます。

// 従来の書き方(元の配列が変わってしまう)
const sorted = original.sort();
console.log(sorted);   // [1, 1, 3, 4, 5]
console.log(original); // [1, 1, 3, 4, 5] ← 書き換わっている

toSorted() を使うと元の配列を保ったまま操作できます。

// toSorted() を使った書き方
const sorted = original.toSorted();
console.log(sorted);   // [1, 1, 3, 4, 5]
console.log(original); // [3, 1, 4, 1, 5] ← 変化なし

同様に toReversed() で元の配列を変えずに逆順にできます。

const reversed = original.toReversed();
console.log(reversed); // [5, 1, 4, 1, 3]
console.log(original); // [3, 1, 4, 1, 5] ← 変化なし

Object.groupBy() ― 配列をグループ分けする

以下のような配列があるとします。

const products = [
  { name: "りんご",   category: "果物" },
  { name: "バナナ",   category: "果物" },
  { name: "にんじん", category: "野菜" },
  { name: "キャベツ", category: "野菜" },
];

Object.groupBy() を使うと、指定したキーでグループ分けした結果を取得できます。

const grouped = Object.groupBy(products, item => item.category);
console.log(grouped);
// {
//   果物: [{ name: "りんご", ... }, { name: "バナナ", ... }],
//   野菜: [{ name: "にんじん", ... }, { name: "キャベツ", ... }]
// }

従来はこれを実現するために reduce() を使った複雑な処理が必要でした。

// 従来の書き方
const grouped = products.reduce((acc, item) => {
  const key = item.category;
  if (!acc[key]) acc[key] = [];
  acc[key].push(item);
  return acc;
}, {});

グループ化後のキー・値の取得

Object.groupBy() の結果は通常のオブジェクトなので、Object.keys() などがそのまま使えます。

// キーだけ取得
console.log(Object.keys(grouped));   // ["果物", "野菜"]

// 値だけ取得
console.log(Object.values(grouped)); // [[{...}, {...}], [{...}, {...}]]

// キーと値をセットで取得
console.log(Object.entries(grouped));
// [["果物", [{...}, {...}]], ["野菜", [{...}, {...}]]]
メソッド取得できるもの
Object.keys(grouped)キーの配列
Object.values(grouped)値(グループごとの配列)の配列
Object.entries(grouped)[キー, 値] のペアの配列

with() ― 特定の要素だけ変えた新しい配列を返す

with(インデックス, 新しい値) で、指定した位置の値だけを変えた新しい配列を返します。

const arr = ["a", "b", "c", "d", "e"];

const newArr = arr.with(2, "X");
console.log(newArr); // ["a", "b", "X", "d", "e"]
console.log(arr);    // ["a", "b", "c", "d", "e"] ← 元は変わらない

負のインデックスも使えます。

const newArr = arr.with(-1, "Z");
console.log(newArr); // ["a", "b", "c", "d", "Z"]

オブジェクトの配列で1件だけ更新したい場合によく使います。

const users = [
  { id: 1, name: "田中", active: true },
  { id: 2, name: "鈴木", active: true },
  { id: 3, name: "佐藤", active: true },
];

const index = users.findIndex(u => u.id === 2);
const updated = users.with(index, { ...users[index], active: false });

console.log(updated);
// [
//   { id: 1, name: "田中", active: true },
//   { id: 2, name: "鈴木", active: false },  ← ここだけ変わっている
//   { id: 3, name: "佐藤", active: true },
// ]
console.log(users); // 元の配列は変わらない

Vue.jsのwatcherとの組み合わせ

非破壊的メソッドの返り値を元の変数に代入することで、Vue.jsのwatcherが変更を検知できます。

// ❌ 代入なし → watcherは検知できない
this.users.with(index, { ...this.users[index], active: false });

// ✅ 代入あり → watcherが検知できる
this.users = this.users.with(index, { ...this.users[index], active: false });
操作watcherが検知できるかdeep: trueが必要か
this.users = this.users.with(...) (代入あり)✅ 検知できる不要
this.users.with(...) (代入なし)❌ 検知できない
this.users[1].active = false (直接変更)✅ 検知できる必要

解説

at() について

at() は配列・文字列・TypedArrayで使えるメソッドです。

引数に 負の数 を渡すことで、末尾からの位置を指定できます。

  • at(-1) → 末尾から1番目(最後の要素)
  • at(-2) → 末尾から2番目
  • at(0) → 先頭の要素(通常の arr[0] と同じ)

→ ES2022で追加されました。


toSorted() / toReversed() / toSpliced() / with() について

これらは配列を 非破壊的に操作する ためのメソッドです。

メソッド説明
toSorted()ソートした新しい配列を返す
toReversed()逆順にした新しい配列を返す
toSpliced()要素を追加・削除した新しい配列を返す
with(index, value)特定インデックスの値を変えた新しい配列を返す

いずれも 元の配列は変更されません。

→ ES2023で追加されました。


Object.groupBy() について

Object.groupBy(配列, グループを返す関数) という形式で使います。

第2引数に渡した関数の 戻り値 がグループのキーになります。

// 数値の偶数・奇数でグループ分けする例
const numbers = [1, 2, 3, 4, 5, 6];
const grouped = Object.groupBy(numbers, n => n % 2 === 0 ? "偶数" : "奇数");
console.log(grouped);
// { 奇数: [1, 3, 5], 偶数: [2, 4, 6] }

→ ES2024で追加されました。


各機能のChrome対応状況

最新のChromeであれば特別な準備なしにそのまま動きます。Chromeのデベロッパーツール(F12)→ Consoleタブで試すことができます。

機能Chrome対応バージョン現在のChromeで動くか
at()Chrome 92〜
toSorted() / toReversed()Chrome 110〜
Object.groupBy()Chrome 117〜
with()Chrome 110〜

古いブラウザ対応が必要な場合や古いNode.js環境ではBabelやPolyfillが必要になる場合があります。


まとめ

今回は、ES2022〜ES2024で追加されたモダンJavaScriptの新機能について解説しました。

特に toSorted() / toReversed() / with() などの非破壊的メソッドは、意図しない配列の書き換えによるバグを防ぐことができます。Vue.jsなどのフレームワークとの相性も良く、積極的に活用してみてください。

※ただし、これらの機能は比較的新しいため、古いブラウザや古いNode.jsのバージョンでは動作しない場合があります。使用する環境のバージョンを事前に確認するようにしましょう。

コメント

タイトルとURLをコピーしました