splice(追加)とは何か
splice は「配列の途中に要素を挿入(必要なら置き換えも)できる」メソッドです。書式は array.splice(start, deleteCount, ...insertItems)。ここが重要です:splice は“破壊的操作”で、元の配列を直接書き換えます。挿入だけなら deleteCount = 0 にし、start 位置に insertItems を差し込みます。戻り値は「削除された要素の配列」なので、挿入だけなら空配列が返ります。
基本の挿入(deleteCount を 0 にする)
指定位置へ 1 件挿入する
const a = ["A", "C", "D"];
const removed = a.splice(1, 0, "B"); // 1番目の位置へ "B" を挿入
console.log(a); // ["A", "B", "C", "D"]
console.log(removed); // [](削除していないので空)
JavaScriptここが重要です:start は「その位置の手前に挿入される」基準。deleteCount = 0 なら“挿入のみ”になります。
複数件をまとめて挿入する
const a = [1, 4, 5];
a.splice(1, 0, 2, 3); // 1番目に 2,3 を連続挿入
console.log(a); // [1, 2, 3, 4, 5]
JavaScriptここが重要です:...insertItems に並べた順で挿入されます。ループで1つずつ挿入するより、まとめて挿入したほうが意図が明確で安全です。
配列を挿入するときの注意(スプレッドで展開)
入れ子にせず“要素として”挿入する
const a = ["A", "D"];
const mid = ["B", "C"];
// 悪い例:配列ごと1要素として挿入される
a.splice(1, 0, mid); // ["A", ["B","C"], "D"]
// 良い例:要素を展開して挿入
a.splice(1, 0, ...mid); // ["A", "B", "C", "D"]
JavaScriptここが重要です:配列そのものを渡すと“入れ子”になります。別配列の中身を挿入したいときはスプレッド(...)で展開しましょう。
挿入と置き換え(削除+挿入を同時に)
1 件置き換える(削除1件+挿入)
const a = ["A", "X", "C"];
const removed = a.splice(1, 1, "B"); // 1件削除し "B" を挿入
console.log(a); // ["A", "B", "C"]
console.log(removed); // ["X"]
JavaScriptここが重要です:“差し替え”は splice 一発でできます。deleteCount が削除件数、insertItems が置き換え後の値です。
範囲を置き換える(複数件)
const nums = [0, 1, 2, 3, 4];
nums.splice(1, 3, 100, 200); // 1番目から3件を 100,200 に置換
console.log(nums); // [0, 100, 200, 4]
JavaScriptここが重要です:挿入する件数と削除する件数が違ってもOK。全体の長さが増減します。
負のインデックス・境界の挙動
負の start(末尾から数える)
const a = ["A", "B", "D"];
a.splice(-1, 0, "C"); // 最後の位置の手前に "C" を挿入
console.log(a); // ["A", "B", "C", "D"]
JavaScriptここが重要です:-1 は「最後の要素の位置」、その手前に挿入されます。末尾近辺の操作が直感的になります。
範囲外 start の扱い
const a = ["A", "B"];
a.splice(999, 0, "C"); // 末尾のさらに後を指定 → 実質末尾に挿入
console.log(a); // ["A", "B", "C"]
JavaScriptここが重要です:start が長さを超えると末尾扱い。負の値で長さより小さくなる場合は 0 に切り上げられます。
非破壊で“挿入した形”を作る(副作用を避ける)
位置指定で前後を結合する
const a = ["A", "C"];
const i = 1;
const inserted = [...a.slice(0, i), "B", ...a.slice(i)];
console.log(inserted); // ["A", "B", "C"]
console.log(a); // ["A", "C"](元は不変)
JavaScriptここが重要です:splice は破壊的。状態管理(React/Vue)や共有配列では非破壊の“前後スライス+スプレッド”が安全です。
複数件の非破壊挿入
const a = [1, 4, 5];
const i = 1, items = [2, 3];
const inserted = [...a.slice(0, i), ...items, ...a.slice(i)];
// [1, 2, 3, 4, 5]
JavaScriptここが重要です:“まとめて展開”すれば入れ子にならず、意図通りの形で新配列を得られます。
実践例(検索後に差し込む・ソート位置へ挿入)
見つけた位置の直前/直後に挿入
const users = [{id:1},{id:3}];
const i = users.findIndex(u => u.id === 3);
if (i !== -1) users.splice(i, 0, { id: 2 }); // 3の直前に挿入
JavaScriptここが重要です:findIndex で“挿入地点”を特定してから差し込む。-1 判定を忘れないことで誤挿入を防げます。
昇順配列へ“適切な位置”に挿入
function insertSorted(arr, x) {
const i = arr.findIndex(v => v > x);
const pos = i === -1 ? arr.length : i;
arr.splice(pos, 0, x);
}
const a = [10, 20, 40];
insertSorted(a, 30); // → [10, 20, 30, 40]
JavaScriptここが重要です:“超えた最初の位置”を探して挿入すると、ソートを保ったまま差し込めます。
よくある落とし穴と回避策
意図せず配列をそのまま挿入して入れ子にしてしまうミスが起きます。別配列の中身を入れるときは必ずスプレッドで展開してください。複数回の splice を前から進めると、挿入でインデックスがずれて次の位置が変わるバグが起こります。後ろから処理する、または非破壊の“スライス+スプレッド”に切り替えると安全です。共有参照の配列に splice を使うと、他のロジックや UI に副作用が伝播します。状態管理では非破壊の挿入パターンを徹底しましょう。deleteCount を書き忘れて意図せず“置き換え”になってしまうことがあります。挿入だけなら必ず deleteCount = 0 を明示してください。
まとめ
splice(追加)は splice(start, 0, ...items) で指定位置に挿入し、置換は削除数を指定して挿入を同時に行えます。負のインデックスで末尾指向の操作が直感的になり、範囲外は末尾扱い。配列の中身を入れるときはスプレッドで展開し、共有状態では非破壊の“スライス+スプレッド”を選ぶ。挿入地点を findIndex などで明確に決め、インデックスずれを避ける——この基本を押さえれば、初心者でも意図通りで壊れにくい挿入が書けます。
