JavaScriptの開発において、配列の操作は避けては通れない基本的な作業の一つです。

データのリストを表示したり、ユーザーの入力を動的に追加したりと、配列に要素を加えるシーンは多岐にわたります。

かつては pushunshift といった破壊的なメソッドが主流でしたが、現代のフロントエンド開発では状態の不変性(イミュータビリティ)が重視されています。

本記事では、基本的な追加手法から、最新のECMAScriptで導入された非破壊的なメソッドまで、2026年現在のスタンダードを網羅して解説します。

JavaScriptの配列操作における「破壊的」と「非破壊的」の違い

配列に要素を追加する方法を学ぶ前に、まず理解しておくべき重要な概念が「破壊的(Mutating)」と「非破壊的(Non-mutating)」の違いです。

破壊的なメソッドは、元の配列そのものを書き換えて変更を加えます。

一方で、非破壊的なメソッドは元の配列を変更せず、新しい配列を生成して返します。

ReactやVue.jsといったモダンなフレームワークでは、データの変更を検知するために非破壊的な操作が強く推奨されています。

不適切な破壊的プログラミングは、予期せぬバグやレンダリングの不具合を引き起こす原因となるため、使い分けが非常に重要です。

この記事を通じて、それぞれのメソッドがどちらの特性を持つのかを正確に把握していきましょう。

末尾に要素を追加する:pushメソッド

配列の最後に新しい要素を追加する最も一般的な方法が push メソッドです。

このメソッドは破壊的であり、実行すると元の配列が直接更新されます。

戻り値として、要素を追加した後の「新しい配列の長さ」を返す点に注意が必要です。

JavaScript
// 数値の配列を用意します
const numbers = [1, 2, 3];

// 末尾に4を追加します
const newLength = numbers.push(4);

console.log(numbers); // 元の配列が変更されている
console.log(newLength); // 戻り値は配列の長さ
実行結果
[1, 2, 3, 4]
4

push は一度に複数の要素を追加することも可能です。

カンマ区切りで引数を渡すことで、指定した順番通りに末尾へ結合されます。

JavaScript
const fruits = ["apple", "orange"];

// 複数の要素を一度に追加
fruits.push("banana", "grape");

console.log(fruits);
実行結果
["apple", "orange", "banana", "grape"]

先頭に要素を追加する:unshiftメソッド

配列の先頭に要素を挿入したい場合は、 unshift メソッドを使用します。

push と同様に破壊的なメソッドであり、既存の要素のインデックスを一つずつ後ろにずらします。

そのため、配列の要素数が非常に多い場合、 push よりも処理コストが高くなる傾向があります。

JavaScript
const colors = ["red", "blue"];

// 先頭にgreenを追加
colors.unshift("green");

console.log(colors);
実行結果
["green", "red", "blue"]

大規模なデータを扱うアプリケーションでは、先頭への追加が頻繁に発生する場合、パフォーマンスへの影響を考慮してデータ構造を見直すことも検討すべきでしょう。

指定した位置に要素を挿入する:spliceメソッド

配列の中間に要素を差し込みたい場合には splice メソッドが適しています。

このメソッドは非常に強力で、要素の追加だけでなく削除や置換も同時に行えます。

第1引数に開始位置(インデックス)、第2引数に削除する個数、第3引数以降に追加したい要素を指定します。

JavaScript
const items = ["A", "B", "D"];

// インデックス2の位置から0個削除し、"C"を追加する
items.splice(2, 0, "C");

console.log(items);
実行結果
["A", "B", "C", "D"]

splice は元の配列を直接操作するため、多用するとコードの可読性や予測可能性を低下させることがあります。

特定の場所へ挿入しつつ、元の配列を維持したい場合は、後述する toSpliced の利用を推奨します。

スプレッド構文を用いた非破壊的な追加

ES6(ECMAScript 2015)で導入されたスプレッド構文(…)は、現代のJavaScriptにおいて最も好まれる追加手法の一つです。

スプレッド構文を使うと、元の配列を展開して新しい配列のリテラル内に配置できます。

これにより、元の配列を一切汚さずに新しい要素を追加した配列を作成できます。

JavaScript
const original = [1, 2, 3];

// 末尾に追加(pushの代替)
const addedEnd = [...original, 4];

// 先頭に追加(unshiftの代替)
const addedStart = [0, ...original];

// 中間に挿入
const addedMiddle = [1, 1.5, ...original.slice(1)];

console.log("Original:", original);
console.log("End:", addedEnd);
console.log("Start:", addedStart);
実行結果
Original: [1, 2, 3]
End: [1, 2, 3, 4]
Start: [0, 1, 2, 3]

スプレッド構文は記述が簡潔であり、宣言的なプログラミングスタイルに適しています。

特にReactの useState などで状態を更新する際には、この書き方がデファクトスタンダードとなっています。

配列同士を結合する:concatメソッド

concat は、既存の配列に別の配列や値を結合し、新しい配列を返す非破壊的なメソッドです。

スプレッド構文が登場する前は、非破壊的な結合の主流でした。

JavaScript
const arr1 = [1, 2];
const arr2 = [3, 4];

// 配列を結合
const combined = arr1.concat(arr2);

console.log(combined);
console.log(arr1); // 元の配列は変わらない
実行結果
[1, 2, 3, 4]
[1, 2]

現在ではスプレッド構文で代用されることが多いですが、結合対象が配列であるか単一の値であるか不明な場合に、安全にフラットな結合を行えるというメリットがあります。

【最新】toSplicedメソッドによる非破壊的な挿入

ECMAScript 2023で導入され、現在(2026年)では主要なブラウザやランタイムで完全にサポートされているのが toSpliced です。

これは splice の非破壊バージョンであり、元の配列を変更せずに、要素を追加・削除した新しい配列を返します。

JavaScript
const base = ["Apple", "Banana", "Date"];

// インデックス2に"Cherry"を挿入した新しい配列を作成
const result = base.toSpliced(2, 0, "Cherry");

console.log("Base:", base);
console.log("Result:", result);
実行結果
Base: ["Apple", "Banana", "Date"]
Result: ["Apple", "Banana", "Cherry", "Date"]

従来の splice は戻り値が「削除された要素の配列」であったため、メソッドチェーンが組めないという欠点がありました。

toSpliced は新しい配列を返すため、他の mapfilter と組み合わせて記述することが容易になります。

特定のインデックスを更新・追加する:withメソッド

配列の特定のインデックスの値を差し替えた新しい配列を作成したい場合は、 with メソッドが便利です。

これも toSpliced と同様に非破壊的なメソッドです。

厳密には「追加」ではなく「置換」ですが、特定の要素を最新の情報にアップデートする際に多用されます。

JavaScript
const list = ["Gold", "Silver", "Bronze"];

// インデックス1を"Platinum"に変更した新しい配列
const updatedList = list.with(1, "Platinum");

console.log(updatedList);
実行結果
["Gold", "Platinum", "Bronze"]

手法別:使い分けの比較表

これまでに紹介した手法を、用途と特性ごとにまとめました。

プロジェクトの要件やコーディング規約に合わせて、最適なものを選択してください。

メソッド名追加位置破壊性主な用途・特徴
push末尾破壊的単純な末尾追加。最も高速。
unshift先頭破壊的先頭への追加。インデックスの再計算が発生。
splice任意破壊的特定位置への挿入・削除を同時に行う。
concat末尾非破壊配列同士の結合に利用。
スプレッド構文任意非破壊モダンな開発での標準。読みやすく直感的。
toSpliced任意非破壊最新仕様。特定位置への非破壊的な挿入。

パフォーマンスに関する考察

JavaScriptエンジンの最適化が進んでいるため、通常のアプリケーション開発で配列操作の速度が問題になることは稀です。

しかし、数万件、数十万件といった膨大なデータを扱う場合は、メソッドの選択が実行速度に影響を与えます。

一般的に、破壊的な push メソッドは最も高速です。

これは新しいメモリ領域を確保してコピーを作成する必要がないためです。

一方で、スプレッド構文や concat は毎回新しい配列を生成するため、ループ内で大量に実行するとメモリ消費量が増加し、ガベージコレクションの頻度が高まる可能性があります。

パフォーマンスが極めて重要な処理(ゲームエンジンや重い計算処理など)では、あらかじめ必要なサイズの配列を確保し、破壊的な操作を行うのが定石です。

逆に、UIの更新を伴うWebアプリケーションでは、パフォーマンスよりも「データがいつ、どこで変わったか」を追跡しやすい非破壊的な操作が優先されます。

実務での使い分け:イミュータブルな状態管理

2026年現在のフロントエンド開発において、直接配列を書き換えるコードは「レガシー」あるいは「要注意」と見なされることが多いです。

例えば、TODOリストに新しい項目を追加する処理を考えてみましょう。

以下のコードは、典型的な非破壊的な追加パターンです。

JavaScript
const [todos, setTodos] = useState(["宿題", "買い物"]);

const addNewTodo = (text) => {
  // pushは使わず、新しい配列を作成してセットする
  setTodos([...todos, text]);
};

このようにスプレッド構文を用いることで、元の todos 配列の参照が変わり、フレームワークは「データが更新された」と正しく認識して画面を再描画します。

もしここで push を使用してしまうと、配列の中身は変わっても「配列自体の参照」が変わらないため、画面が更新されないというトラブルを招きます。

まとめ

JavaScriptで配列に要素を追加する方法は、言語の進化とともに多様化してきました。

基本となる pushunshift だけでなく、スプレッド構文や最新の toSpliced といった非破壊的な手法を使いこなすことが、現代のエンジニアには求められています。

「元の配列を壊して良いか(破壊的)」それとも「新しい配列が必要か(非破壊的)」という視点でメソッドを選択しましょう。

それぞれの特徴を理解し、パフォーマンスとコードの堅牢性のバランスを考慮したプログラミングを心がけてください。

今回紹介した手法をマスターすれば、複雑なデータ操作も安全かつスマートに実装できるはずです。