【JavaScript】配列の最初と最後の要素を取得・判定する方法|at(-1)・分割代入・forEach 内の判定・空配列チェックまで解説

配列の最初の要素最後の要素を取得する操作や、ループ内で「今処理しているのが先頭か末尾か」を判定する操作は、JavaScript の配列処理で頻出します。ES2022 の at(-1) メソッドの登場で末尾の取得が格段に簡潔になりました。

この記事でわかること
・arr[0] と arr[arr.length – 1] の基本
・at(-1) で末尾を簡潔に取得する方法(ES2022)
・分割代入で先頭と残りを分離する方法
・forEach / map のループ内で先頭・末尾を判定する方法
・shift / pop との違い(破壊的 vs 非破壊的)
・空配列のチェック
・findLast / findLastIndex で末尾から条件検索
・区切り文字の出し分け・リストのスタイル制御の実務パターン
スポンサーリンク

最初・最後の要素を取得する方法の比較

方法 最初 最後 破壊的 空配列時
ブラケット記法 arr[0] arr[arr.length - 1] × undefined
at() arr.at(0) arr.at(-1) × undefined
分割代入 const [first] = arr const last = arr.at(-1) × undefined
shift / pop arr.shift() arr.pop() ○ 破壊的 undefined

ブラケット記法(基本)

JavaScript
const fruits = ["りんご", "みかん", "ぶどう", "いちご", "メロン"];

// 最初の要素
console.log(fruits[0]); // "りんご"

// 最後の要素
console.log(fruits[fruits.length - 1]); // "メロン"

// 元の配列は変更されない
console.log(fruits.length); // 5

at() メソッドで簡潔に取得する(ES2022)

at() メソッドは正負のインデックスに対応しており、arr.at(-1) で末尾を取得できます。arr[arr.length - 1] と比べて格段に読みやすくなります。

JavaScript
const arr = [10, 20, 30, 40, 50];

console.log(arr.at(0));  // 10(先頭)
console.log(arr.at(-1)); // 50(末尾)
console.log(arr.at(-2)); // 40(末尾から2番目)

// 空配列
console.log([].at(0));  // undefined
console.log([].at(-1)); // undefined
at(-1) はメソッドチェーンの中でも使えます。arr.filter(fn).at(-1) のように、フィルタ結果の最後の要素を取得する場面で特に便利です。
メソッドチェーンでの活用
const scores = [85, 92, 78, 96, 88, 91];

// 90点以上の最後のスコア
const lastHigh = scores.filter(s => s >= 90).at(-1);
console.log(lastHigh); // 91

分割代入で先頭と残りを分離する

JavaScript
const arr = [1, 2, 3, 4, 5];

// 先頭を取得
const [first] = arr;
console.log(first); // 1

// 先頭と残りを分離(レスト構文)
const [head, ...rest] = arr;
console.log(head); // 1
console.log(rest); // [2, 3, 4, 5]

// 先頭2つと残り
const [a, b, ...others] = arr;
console.log(a, b);   // 1, 2
console.log(others); // [3, 4, 5]

末尾を分割代入で取得するテクニック

JavaScript
const arr = [1, 2, 3, 4, 5];

// 末尾を分離(reverse + 分割代入)
const [last, ...init] = [...arr].reverse();
console.log(last); // 5
console.log(init.reverse()); // [1, 2, 3, 4]

// at(-1) の方がシンプル
console.log(arr.at(-1)); // 5
末尾の取得には分割代入より at(-1) の方がシンプルです。分割代入は先頭と残りを同時に取り出す場面に適しています。

shift / pop との違い(破壊的 vs 非破壊的)

メソッド 動作 元の配列
arr[0] / at(0) 先頭を取得(参照のみ) 変更されない
arr.shift() 先頭を削除して返す 変更される
arr[arr.length - 1] / at(-1) 末尾を取得(参照のみ) 変更されない
arr.pop() 末尾を削除して返す 変更される
JavaScript
const arr = [1, 2, 3, 4, 5];

// at: 取得のみ(非破壊的)
console.log(arr.at(-1)); // 5
console.log(arr.length); // 5(変わらない)

// pop: 取得 + 削除(破壊的)
console.log(arr.pop());  // 5
console.log(arr.length); // 4(1つ減った)
「取得」だけなら at() やブラケット記法を使いましょう。shift / pop は配列を変更するため、取得目的だけで使うと意図せずデータが消えてしまいます。

forEach / map のループ内で先頭・末尾を判定する

ループ処理の中で「今の要素が最初か?最後か?」を判定するには、コールバックの第 2 引数(インデックス)を使います。

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

items.forEach((item, index, array) => {
  const isFirst = index === 0;
  const isLast = index === array.length - 1;

  if (isFirst) console.log(`先頭: ${item}`);
  if (isLast)  console.log(`末尾: ${item}`);
});
// "先頭: A"
// "末尾: D"
map で先頭・末尾だけスタイルを変える
const items = ["ホーム", "製品", "会社概要", "お問い合わせ"];

const html = items.map((item, i, arr) => {
  const classes = [];
  if (i === 0) classes.push("first");
  if (i === arr.length - 1) classes.push("last");
  return `<li class="${classes.join(" ")}">${item}</li>`;
}).join("\n");

console.log(html);
// <li class="first">ホーム</li>
// <li class="">製品</li>
// <li class="">会社概要</li>
// <li class="last">お問い合わせ</li>

空配列のチェック

空配列に arr[0]at(-1) を使うと undefined が返ります。エラーにはなりませんが、後続の処理でプロパティアクセスするとエラーになるため、空チェックを入れましょう。

JavaScript
const arr = [];

// undefined が返る
console.log(arr[0]);    // undefined
console.log(arr.at(-1)); // undefined

// 空チェック
if (arr.length > 0) {
  console.log("先頭:", arr[0]);
  console.log("末尾:", arr.at(-1));
} else {
  console.log("配列が空です");
}

// Nullish coalescing で代替値
console.log(arr.at(0) ?? "デフォルト値");

findLast / findLastIndex で末尾から条件検索する(ES2023)

find は先頭から検索しますが、findLast(ES2023)は末尾から検索して最初に条件に合う要素を返します。

JavaScript
const nums = [1, 4, 7, 2, 9, 3, 8];

// 先頭から検索: 最初の5以上
console.log(nums.find(n => n >= 5));     // 7

// 末尾から検索: 最後の5以上
console.log(nums.findLast(n => n >= 5)); // 8

// 末尾から検索: 最後の5以上のインデックス
console.log(nums.findLastIndex(n => n >= 5)); // 6
メソッド 検索方向 戻り値
find(fn) 先頭 → 末尾 最初に条件に合う要素
findLast(fn) 末尾 → 先頭 最後に条件に合う要素
findIndex(fn) 先頭 → 末尾 最初に条件に合うインデックス
findLastIndex(fn) 末尾 → 先頭 最後に条件に合うインデックス

実務でよく使うパターン

区切り文字の出し分け(最後だけカンマなし)

JavaScript
const tags = ["JavaScript", "TypeScript", "React"];

// join で一発(最もシンプル)
console.log(tags.join(", ")); // "JavaScript, TypeScript, React"

// ループ内で判定する場合
let result = "";
tags.forEach((tag, i, arr) => {
  result += tag;
  if (i < arr.length - 1) result += ", "; // 最後以外にカンマ
});
console.log(result); // "JavaScript, TypeScript, React"

パンくずリストの最後の要素だけリンクなしにする

JavaScript
const breadcrumbs = [
  { label: "ホーム", url: "/" },
  { label: "ブログ", url: "/blog" },
  { label: "記事タイトル", url: null } // 現在ページ
];

const html = breadcrumbs.map((item, i, arr) => {
  if (i === arr.length - 1) {
    return `<span class="current">${item.label}</span>`;
  }
  return `<a href="${item.url}">${item.label}</a> &gt; `;
}).join("");

console.log(html);
// <a href="/">ホーム</a> &gt; <a href="/blog">ブログ</a> &gt; <span class="current">記事タイトル</span>

キューの先頭を処理して取り出す

JavaScript
const queue = ["タスクA", "タスクB", "タスクC"];

// 先頭を確認(非破壊)
console.log("次のタスク:", queue.at(0)); // "タスクA"

// 先頭を処理して取り出す(破壊的)
const current = queue.shift();
console.log("処理中:", current);  // "タスクA"
console.log("残り:", queue);      // ["タスクB", "タスクC"]

関連記事

よくある質問

Q配列の最後の要素を取得する最もシンプルな方法は?
Aarr.at(-1) が最もシンプルです(ES2022)。従来は arr[arr.length - 1] と書く必要がありました。
Qat(-1) と pop() の違いは?
Aat(-1) は要素を取得するだけで配列を変更しません(非破壊的)。pop() は末尾の要素を削除して返します(破壊的)。取得のみなら at を使いましょう。
QforEach 内で現在の要素が最後かどうかを判定するには?
Aコールバックの第 3 引数(元の配列)を使い、index === array.length - 1 で判定します。items.forEach((item, index, array) => { if (index === array.length - 1) { ... } })
Q空配列に at(0) や at(-1) を使うとエラーになりますか?
Aエラーにはなりません。undefined が返ります。ただし undefined.textContent のように後続のプロパティアクセスはエラーになるため、arr.length > 0 で空チェックするか arr.at(0) ?? "デフォルト値" で代替値を設定してください。
QfindLast はどのブラウザで使えますか?
AfindLast / findLastIndex は ES2023 で策定され、Chrome 97+・Firefox 104+・Safari 15.4+ で対応しています。IE は非対応です。

まとめ

配列の最初と最後の要素を取得・判定する方法を整理しました。

  • 先頭取得: arr[0] / arr.at(0) / const [first] = arr
  • 末尾取得: arr.at(-1)(推奨)/ arr[arr.length - 1]
  • ループ内判定: index === 0(先頭)/ index === array.length - 1(末尾)
  • 末尾から検索: findLast(fn)(ES2023)
  • 注意: shift / pop は破壊的。取得のみなら at を使う

区切り文字の出し分けやパンくずリストの末尾処理など、ループ内での先頭・末尾判定は実務で頻出します。at(-1) を覚えておくだけでコードの可読性が大幅に向上します。