Array.prototype.at()
Returns the element at an index, counting back from the end when the index is negative.
at(index)- Added in JavaScript ECMAScript 2022
Parameters
| Parameter | Type | Description |
|---|---|---|
$index | number | Zero-based index, converted to an integer. If negative, index + array.length is accessed. |
Return value
anyThe element at the given index, or undefined when the index is out of range.
Errors
Throws a TypeError only when called on null or undefined; out-of-range indexes return undefined instead of throwing.
at() exists for one reason: reading from the end of an array without repeating the expression. arr.at(-1) replaces arr[arr.length - 1], which matters when arr is actually getRows(filter)[…] and you would otherwise call it twice or bind a temporary.
When to reach for it
Any time you want the last, second-to-last, or n-from-the-end element — the newest log line, the final path segment, the top of a stack you are not popping. It is also the readable choice inside chains: list.toSorted(byScore).at(-1).
What trips people up
- Negative indexes only work with
at().arr[-1]is a plain string property named"-1", not the last element, and it returnsundefinedunless someone set it. - Out-of-range access returns
undefinedwithout an error, soat()never distinguishes "missing" from "holds undefined". Compare againstlengthif you need that. - The index is converted to an integer:
at(1.7)reads index 1 andat("1")reads index 1, whileat(undefined)andat(NaN)read index 0. - Only reading is supported.
at()cannot assign — use with() for a copying write.
The same method exists on strings and typed arrays, so the negative-index habit transfers.
Example
When to use it
- Grab the most recent entry from a log or history array with at(-1).
- Read the file extension segment after splitting a path on ".".
- Peek at the top of a stack without popping it.
- Pull the highest-scoring row straight out of a toSorted() chain.
Frequently asked questions
How do I get the last element of an array in JavaScript?
Call arr.at(-1) — negative indexes count back from the end, so -1 is the last element. It returns undefined for an empty array rather than throwing.
Why does arr[-1] return undefined?
Bracket notation converts -1 to the string property name "-1", which arrays do not define. Only at() interprets negative numbers as offsets from the end.
Can I assign a value with at()?
No, at() is read-only and there is no setter counterpart. Use arr.with(-1, value) for a copy with the last element replaced, or arr[arr.length - 1] = value to mutate in place.
More examples
Avoiding a repeated expression
Both print 9. The second form reads the last element of an anonymous intermediate array, which bracket notation cannot do without naming it.
const rows = [{ score: 3 }, { score: 9 }, { score: 5 }];
// Without at(): the sorted array must be stored first
const sorted = rows.toSorted((a, b) => a.score - b.score);
console.log(sorted[sorted.length - 1].score);
// With at(): one expression, no temporary
console.log(rows.toSorted((a, b) => a.score - b.score).at(-1).score);Index coercion rules
The argument goes through integer conversion, so fractions truncate and non-numeric values become 0. Index -3 is the first element; -4 falls off the front and yields undefined.
const a = ["a", "b", "c"];
console.log(a.at(1.9)); // truncated toward zero
console.log(a.at("2")); // string is converted
console.log(a.at(undefined)); // NaN -> 0
console.log(a.at(-0)); // 0
console.log(a.at(-3), a.at(-4));Works on strings and typed arrays too
at() is generic: it only needs a length property and integer keys, which is why the same negative-index syntax works across strings, typed arrays and plain array-like objects.
console.log("soundscode".at(-1));
console.log(new Int8Array([1, 2, 3]).at(-1));
// And on array-likes via call()
const arrayLike = { length: 2, 0: "x", 1: "y" };
console.log(Array.prototype.at.call(arrayLike, -1));
Discussion