JavaScript | 配列・オブジェクト:配列の追加・削除 – pop

JavaScript JavaScript
スポンサーリンク

pop とは何か

pop は「配列の末尾から要素を1つ取り出して、配列から削除する」メソッドです。取り出した要素を返し、配列の長さを1つ減らします。ここが重要です:pop は“破壊的操作”で、元の配列を直接書き換えます。空配列に対して pop を呼ぶと、戻り値は undefined で、長さは 0 のままです。


基本の使い方と戻り値の扱い

末尾の要素を取り出す

const a = [10, 20, 30];
const last = a.pop();
console.log(last); // 30(取り出した要素)
console.log(a);    // [10, 20](末尾が削除された)
JavaScript

ここが重要です:戻り値は「削除された末尾要素」です。取り出した後の末尾を参照したいなら a.at(-1) や a[a.length – 1] を使います。

空配列の pop(安全に判定する)

const a = [];
const x = a.pop();
console.log(x); // undefined
console.log(a.length); // 0
JavaScript

ここが重要です:pop の戻り値で「要素があったかどうか」を判定できます。0 や “” など“falsy”な値も正当な要素になり得るため、単に if (!x) で判定しないこと(undefined だけを判定する)。


破壊的操作の注意と非破壊の代替

共有参照への影響(同じ配列が同時に変わる)

const a = [1, 2, 3];
const alias = a; // 同じ配列参照
a.pop();
console.log(alias); // [1, 2](alias も同時に変化)
JavaScript

ここが重要です:pop は元を変えます。状態管理(React/Vue)や他の変数と共有している配列では、副作用を避けるため“非破壊”の代替を選ぶのが安全です。

非破壊で“末尾を除いた新配列”を得る

const a = [1, 2, 3];
const withoutLast = a.slice(0, -1); // [1, 2]
const also = [...a].slice(0, -1);   // スプレッド+slice でも同様
JavaScript

ここが重要です:slice(0, -1) は元配列を壊さずに“最後を除いた新配列”を返します。差分検知や副作用回避に向いています。


pop と他メソッドの違い(使い分けの基準)

shift(先頭から取り出す)との比較

const a = [10, 20, 30];
console.log(a.pop());   // 30(末尾)
console.log(a.shift()); // 10(先頭)
JavaScript

ここが重要です:shift は“先頭”に触るため、要素を全体的に詰めるコストがかかり、配列が大きいほど遅くなりがちです。性能重視なら末尾操作(push/pop)に寄せるのが定石です。

末尾参照の典型パターン

const a = [10, 20, 30];
const tail = a.at(-1); // 30(参照のみ)
const removed = a.pop();// 30(削除+返却)
JavaScript

ここが重要です:単に「末尾を見たい」だけなら at(-1)。削除したいなら pop。意図が明確になります。


実践例(スタック・Undo・取り込み処理)

スタック(LIFO)の基本操作

const stack = [];
stack.push("A");
stack.push("B");
console.log(stack.pop()); // "B"
console.log(stack.pop()); // "A"
JavaScript

ここが重要です:push で積み、pop で最後に積んだものを取り出す。LIFO(後入れ先出し)の定番構造です。

Undo 履歴(最後の操作を取り消す)

const history = ["draw-line", "fill", "erase"];
const lastAction = history.pop();
applyUndo(lastAction); // 取り消し処理
JavaScript

ここが重要です:履歴を末尾に積み、直近を pop で取り消すのは直感的でバグが少ない運用です。

“読み切る”処理(末尾から安全に取り込む)

const queue = [1, 2, 3, 4, 5];
while (queue.length > 0) {
  const item = queue.pop();
  process(item);
}
JavaScript

ここが重要です:length を条件にすれば、空配列でも安全に終了できます。pop の戻り値で undefined を踏む心配がありません。


複数要素をまとめて取り除く(ループと短縮テク)

n 件まとめて末尾から取り除く

function popN(arr, n) {
  const removed = [];
  for (let i = 0; i < n && arr.length > 0; i++) {
    removed.push(arr.pop());
  }
  return removed; // 取り除いた要素(末尾からの順)
}
const a = [1, 2, 3, 4];
console.log(popN(a, 2)); // [4, 3]
console.log(a);          // [1, 2]
JavaScript

ここが重要です:必要数と残数を両方考慮して安全に取り除けます。返り値の順序は「取り出した順(末尾から)」である点に注意。

“戻り値は不要、削除だけしたい”なら length 直接操作

const a = [1, 2, 3, 4];
a.length = Math.max(0, a.length - 2); // 末尾を2つ切り落とす
console.log(a); // [1, 2]
JavaScript

ここが重要です:length を縮めると末尾が消えます。戻り値(取り除いた要素)が不要なときに短く書けます。ただし意図が読みづらくなる場面では pop を明示したほうが親切です.


よくある落とし穴と回避策

空配列で pop して undefined を“意味のある値”と誤判定することがあります。戻り値の判定は undefined で比較する、または length を条件にしてください。取り出し値が 0 や “” のときに if (!x) と書くと誤って「無い」と扱われます。必ず x === undefined で判別します。参照共有のまま pop すると他所の状態が同時に変わり、UIが更新されない・ロジックが破綻するなどの副作用が出ます。非破壊の代替(slice で末尾除去)に切り替えると安全です。大量データで先頭操作(shift)を混在させると性能が落ちます。末尾操作(push/pop)中心の設計に寄せるか、適切なデータ構造(両端キューなど)を検討しましょう。


まとめ

pop は「末尾を取り出して削除する」破壊的メソッドで、戻り値に取り出した要素を返します。空配列なら undefined を返すため、判定は length か undefined 比較で安全に。性能や副作用を考えると、共有状態では非破壊の代替(slice で末尾除去)を選び、スタックや Undo のような LIFO では pop が最適。末尾参照は at(-1)、削除は pop——目的に応じて使い分ければ、初心者でも読みやすく壊れにくい配列削除が書けます。

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