Ribbit's works

JavaScriptにおける配列操作のスタンダード【ES2023】

#JavaScript #TypeScript #配列 #ES2023 #ベストプラクティス
にメンテナンス済み
記事のトップ画像

IE が廃止されたことによって、EcmaScript で新しく追加された記法を気軽に実装できるようになりました。

このページでは、各ブラウザに対応した最新の記法を使って、配列の追加、削除、更新を処理する方法を紹介します。

使用する関数

先にこのページで解説する関数を紹介します。Array.toSplicedです。

Array.prototype.toSpliced() - JavaScript | MDN

配列の追加、削除、更新いずれの操作も、Array.toSplicedを使って処理します。

const array = ['A', 'B', 'C'];

// 配列の末尾に要素を追加
const addedArray = array.toSpliced(array.length, 0, 'D'); // ["A", "B", "C", "D"]

// 配列の先頭の要素を削除
const removedArray = array.toSpliced(0, 1); // ["B", "C"]

// 配列の途中に要素を更新
const updatedArray = array.toSpliced(1, 1, 'X'); // ["A", "X", "C"]

これらの実装を見て気付くことがあるかもしれませんが、Array.toSplicedArray.spliceと同様の動作を、元の配列を変更せずに新しい配列として返します。

なぜこの実装が望ましいのか、次のセクションで解説します。

その他の実装方法

配列を操作する関数は様々あります。例えば、配列を追加する方法に限っても、pushunshiftspliceconcat などがあります。

const array = ['A', 'B', 'C'];

// 配列の末尾に要素を追加
array.push('D'); // ["A", "B", "C", "D"]

// 配列の先頭に要素を追加
array.unshift('Z'); // ["Z", "A", "B", "C", "D"]

// 配列の途中に要素を追加
array.splice(2, 0, 'X'); // ["Z", "A", "X", "B", "C", "D", "E", "F"]

// 配列の末尾に別の配列を追加
const concatenated = array.concat(['E', 'F']); // ["Z", "A", "B", "C", "D", "E", "F"]

pushunshiftspliceは、元の配列を変更します。concatは新しい配列を返すため、新たに変数に代入する必要があります。

このうち、pushunshiftspliceは、元の配列を変更するため、不変性を保つためには注意が必要です。

不変性を保つ

不変性を保つことは、プログラムの品質を高めるために重要です。不変性を保つことで、予測可能なコードを書くことができ、バグを減らすことができます。

例えば、Array.pushを使っていた場合、元の配列を変更してしまうため、予期せぬバグが発生する可能性があります。

以下のようなケースを考えてみましょう。

const exportArray = (array) => {
  array.push('D');
  // 配列をJson形式で出力
};

重要とならない処理は割愛していますが、exportArrayは配列を受け取り、その末尾に要素を追加してから、Json 形式で出力する関数です。

あくまでこの関数の意図としては、配列を変更することではなく、出力することです。しかし、Array.pushを使ってしまうと、元の配列が変更されてしまいます。

そのため、exportArrayの呼び出し元から見ると、予期せぬバグが発生してしまう可能性があります。

const array = ['A', 'B', 'C'];
exportArray(array);
console.log(array); // ["A", "B", "C", "D"]

この部分だけ見て、arrayが初期値でない可能性に気付くことは難しいでしょう。

書き換わっているかどうかを判断するには、exportArrayの中身を見ないとわかりません。このようなバグを防ぐためには、不変性を保つことが重要です。

Array.toSplicedを使った場合

Array.toSplicedを使うと、元の配列を変更せずに新しい配列を返すことができます。

const exportArray = (array) => {
  const newArray = array.toSpliced(array.length, 0, 'D');
  // 配列をJson形式で出力
};

このように書くことで、元の配列を変更することなく、新しい配列を生成することができます。

const array = ['A', 'B', 'C'];
exportArray(array);
console.log(array); // ["A", "B", "C"]

もちろんArray.toSplicedではなく、スプレッド構文やArray.concatを使っても同様の効果を得ることができます。

ベストプラクティスは?

この記事のタイトルを「ベストプラクティス」ではなく「スタンダード」としたのは、ベストプラクティスは状況によって異なるためです。

多くの場合、今回紹介したArray.toSplicedで実装することが望ましいですが、状況によっては他の実装方法が適している場合もあります。

例えば、厳格なリソース制約がある場合、Array.toSplicedでは常に新しい配列を生成するため、メモリ使用量が増えることがあります。その場合は、Array.pushArray.spliceを使うことも検討する必要があります。

そのため、ベストプラクティスを選択する際には、状況に応じて柔軟に対応することが重要です。

まとめ

JavaScript における配列操作は、プログラムの品質を高めるために重要です。不変性を保つことで、予測可能なコードを書くことができ、バグを減らすことができます。

Array.toSplicedを使うことで、元の配列を変更せずに新しい配列を返すことができます。しかし、ベストプラクティスは状況によって異なるため、柔軟に対応することが重要です。