JavaScriptにおける配列操作のスタンダード【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.toSpliced
はArray.splice
と同様の動作を、元の配列を変更せずに新しい配列として返します。
なぜこの実装が望ましいのか、次のセクションで解説します。
その他の実装方法
配列を操作する関数は様々あります。例えば、配列を追加する方法に限っても、push
、unshift
、splice
、concat
などがあります。
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"]
push
、unshift
、splice
は、元の配列を変更します。concat
は新しい配列を返すため、新たに変数に代入する必要があります。
このうち、push
、unshift
、splice
は、元の配列を変更するため、不変性を保つためには注意が必要です。
不変性を保つ
不変性を保つことは、プログラムの品質を高めるために重要です。不変性を保つことで、予測可能なコードを書くことができ、バグを減らすことができます。
例えば、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.push
やArray.splice
を使うことも検討する必要があります。
そのため、ベストプラクティスを選択する際には、状況に応じて柔軟に対応することが重要です。
まとめ
JavaScript における配列操作は、プログラムの品質を高めるために重要です。不変性を保つことで、予測可能なコードを書くことができ、バグを減らすことができます。
Array.toSpliced
を使うことで、元の配列を変更せずに新しい配列を返すことができます。しかし、ベストプラクティスは状況によって異なるため、柔軟に対応することが重要です。