JavaScript

JavaScriptのat():配列の末尾から要素を取得する

この記事でわかること

Array.prototype.at()で配列の末尾や末尾から2番目の要素を取得する方法を解説。ブラウザーとNode.jsの実行手順、空配列・範囲外の扱い、参照共有の注意点を学べます。

目的:末尾から数える処理を読みやすくする

操作履歴の最後の項目や、直近の測定値を取り出すとき、配列の長さから添字を計算することがあります。Array.prototype.at()を使うと、最後はat(-1)、最後から2番目はat(-2)と書けます。

この記事では、配列の指定位置から1つの要素を取り出すat()だけを詳しく扱います。配列を削除・並べ替えせず、末尾に対する相対的な位置をコードに表せる点が目的です。

JavaScript
const history = ["下書き", "確認", "公開"];

console.log(history[history.length - 1]);
console.log(history.at(-1));

期待出力は次のとおりです。どちらも最後の要素を読み取ります。

CODE
公開
公開

at()は条件に合うデータを探す機能ではありません。「どの位置を読むか」が決まっている場面で使います。配列の相対位置を指定できる仕様はMDNのArray.prototype.at()で確認できます。

動作環境と対応バージョン

at()は対応するブラウザーとNode.jsの両方で利用できます。DOMやネットワークを必要としないため、この記事のJavaScriptコードは両環境で同じものを使えます。

MDNは、2022年3月以降、主要ブラウザー間で広く利用できる機能と説明しています。ブラウザーで試す場合は、更新されたChrome、Edge、Firefox、Safariを使用し、実際の環境で機能の有無も確認してください。Firefoxでは90から追加されていることがFirefox 90の開発者向けリリースノートに記載されています。

Node.jsでは16.6.0で追加されました。Node.js 16.6.0の公式リリースノートには、V8の更新とともにArray.prototype.atの導入が明記されています。この番号は機能の導入版であり、新しい環境を用意する際に古い16系を選ぶ理由にはなりません。

機能の有無を確認する

ブラウザーの開発者ツールのConsole、またはNode.jsで次を実行します。

JavaScript
console.log(typeof Array.prototype.at);

対応環境の期待出力はfunctionです。undefinedなら、その環境には組み込まれていません。非対応環境でitems.at(-1)をそのまま呼ぶと、通常はTypeErrorになります。

古い環境も対象なら、環境を更新するか、末尾の読み取りをitems[items.length - 1]で表す方法を検討します。この書き方は最後の要素を読む代替であり、任意の引数を扱うat()全体の代替実装ではありません。

引数と戻り値

基本形はitems.at(index)です。配列自身のメソッドとして呼び出し、引数indexに読み取り位置を指定します。

  • 0は先頭、1は先頭から2番目を表します。
  • -1は最後、-2は最後から2番目を表します。
  • 戻り値はその位置の要素そのものです。
  • 範囲外の位置ではundefinedを返します。

長さが3の配列なら、at(-3)は先頭、at(-4)は範囲外です。負の位置は配列の長さを足した位置として解釈されます。

引数は整数として解釈される

indexは整数へ変換されます。小数はゼロ方向に切り捨てられるため、1.9は1、-1.9は-1に相当します。入力フォームから受け取った位置などは、意図しない変換を避けるため、呼び出し前に整数として妥当か確認する設計が適しています。

JavaScript
const values = [10, 20, 30];

console.log(values.at(1.9));
console.log(values.at(-1.9));
console.log(values.at(3));
console.log(values.at(-4));

期待出力は次のとおりです。

CODE
20
30
undefined
undefined

自己完結したコードを実行する

次のコードは、更新履歴から最後と最後から2番目の項目を取得します。外部ライブラリー、通信、事前に定義した関数は必要ありません。

JavaScript
(() => {
  "use strict";

  if (typeof Array.prototype.at !== "function") {
    console.log("この環境はArray.prototype.atに対応していません");
    return;
  }

  const updates = [
    { id: "draft", label: "下書きを保存" },
    { id: "review", label: "レビューを依頼" },
    { id: "publish", label: "記事を公開" }
  ];

  console.log(`先頭: ${updates.at(0).label}`);
  console.log(`最後: ${updates.at(-1).label}`);
  console.log(`最後から2番目: ${updates.at(-2).label}`);
  console.log(`範囲外: ${updates.at(-4)}`);
  console.log(`要素数: ${updates.length}`);

  const empty = [];
  const latest = empty.at(-1);

  if (latest === undefined) {
    console.log("空配列: 履歴はありません");
  } else {
    console.log(`空配列: ${latest.label}`);
  }
})();

ブラウザーでの実行方法

更新された対応ブラウザーで通常のWebページを開き、開発者ツールのConsoleを選びます。上のコード全体を貼り付けて実行してください。即時実行関数の内側に変数を置いているため、同じコードを繰り返してもトップレベルの変数宣言が衝突しません。

Node.jsでの実行方法

上のコードをUTF-8のarray-at-demo.cjsとして保存します。ターミナルで保存先へ移動し、次のコマンドを実行します。.cjsを使うことで、周囲のプロジェクトのモジュール設定に左右されにくくできます。

Shell
node --version
node array-at-demo.cjs

最初のコマンドでバージョンを確認できます。機能の導入版は16.6.0です。コードにも対応確認を入れているので、未対応なら説明文を表示して終了します。

期待出力

対応環境では、次の6行が順番に表示される想定です。これは仕様に基づいて静的に確認した期待出力であり、実機で実行した結果ではありません。

CODE
先頭: 下書きを保存
最後: 記事を公開
最後から2番目: レビューを依頼
範囲外: undefined
要素数: 3
空配列: 履歴はありません

失敗例と制約

角括弧の負数とは意味が異なる

items[-1]は最後の要素を取得する書き方ではありません。"-1"という名前のプロパティを読みます。通常の配列ではそのプロパティがないため、undefinedになります。

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

console.log(items[-1]);
console.log(items.at(-1));

期待出力はundefinedとCです。末尾から読みたいときに角括弧へ負数を書くと、意図した要素を取得できません。

空配列の要素からプロパティを読まない

at()が範囲外で返すundefinedは、取得後のプロパティアクセスを安全にするものではありません。

JavaScript
const records = [];

try {
  console.log(records.at(-1).label);
} catch (error) {
  console.log(error instanceof TypeError);
}

期待出力はtrueです。例外はat(-1)の取得自体ではなく、その戻り値から.labelを読もうとした箇所で起きます。通常の表示処理では、先ほどの実行例のように取得後の値を確認して分岐させます。

また、要素としてundefinedを保存している場合も戻り値はundefinedです。戻り値だけでは「範囲外」と「存在する要素の値がundefined」を区別できません。要素がオブジェクトであるという前提を決めるか、位置と長さも確認してください。

取得したオブジェクトはコピーされない

at()による読み取りは配列を変更しませんが、オブジェクト要素を取得すると元の要素と同じ参照を受け取ります。

JavaScript
const tasks = [{ title: "確認する", done: false }];
const latest = tasks.at(-1);

latest.done = true;
console.log(tasks[0].done);

期待出力はtrueです。更新履歴を表示するだけなら、取得した値を読み取る用途に限定すると扱いやすくなります。編集用データを独立させたい場合は、別途コピーの方針が必要です。

at()は同期処理で、Promiseを返しません。配列にPromiseが入っていれば、そのPromise自体を返すだけです。データ取得の完了を待つ処理は、呼び出し元で管理してください。

活用事例:最後の項目に業務上の意味を持たせる

at(-1)は、追加順に保存した操作履歴、時刻順に並んだ測定値、パンくず用の階層データなどに向いています。最後から2つの測定値を取得すれば、直前との差分を計算する処理にも使えます。

ただし、「最後の要素」と「最新のデータ」は同じとは限りません。APIが降順で返すなら最新項目は先頭です。ページ分割された一覧の最後は、そのページ内の最後にすぎません。at()は並び順や日時を判断しないため、データの契約を先に確認します。

実装を改善するなら、位置の短い書き方だけでなく、空データ時の表示も同時に決めるのがおすすめです。「履歴はありません」と表示するのか、表示領域を隠すのかを決めれば、取得成功時だけを想定したコードを避けられます。

公式参考資料

仕様と互換性の確認日は2026年10月6日です。利用環境を変更するときは、公式資料と実際の機能検出を併せて確認してください。

PREFERRED SOURCES

Googleの優先するニュース提供元にSEの部屋を追加

Googleで、いつも読みたい情報源を選べます。登録可否はGoogleの画面で確認できます。

Googleの設定画面で確認する 新しいタブで開きます

候補にSEの部屋が表示されない場合は、まだ追加できません。

y.
WRITTEN BY

y_ymo10

SEの部屋で、HTML・CSSからJavaScript・React・Next.jsまで、Web制作の開発ノートを公開しています。

ほかの開発ノートを読む →