Lesson 33 of 80
arr[-1] doesn't get you the last element in JavaScript, no matter how many other languages taught you it should. .at(-1) is the method that actually does.
10 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
In Python, arr[-1] means "the last element." In JavaScript, arr[-1] means "look up a property literally named -1" — which almost never exists on an array, so you silently get undefined instead of an error, instead of the value you wanted.
Array.prototype.at(index) was added (ES2022) specifically to give arrays real negative-index support: arr.at(-1) is the last element, arr.at(-2) is the second-to-last, and so on, while arr.at(0) and positive indices behave exactly like normal bracket access.
const queue = ["a", "b", "c"];
queue[-1];
// undefined -- looked up a property called "-1", found nothing
queue[queue.length - 1];
// "c" -- the traditional way to get the last element
queue.at(-1);
// "c" -- same result, reads like what you meant
The reason arr[-1] doesn't throw is the real trap. JavaScript array indexing is just property access under the hood — arr[i] converts i to a string and looks up that property key on the object. Arrays have real numeric-index properties like "0", "1", "2", but "-1" isn't one JavaScript ever assigns automatically. So arr[-1] doesn't crash, it just quietly returns undefined, which is far more dangerous — a bug that doesn't announce itself.
.at() fixes this by actually implementing offset-from-the-end semantics, not relying on property lookup:
function lastTwo(arr) {
return [arr.at(-2), arr.at(-1)];
}
lastTwo(["x", "y", "z"]);
// ["y", "z"]
lastTwo(["only"]);
// [undefined, "only"] -- still safe, no crash, just undefined for the missing one
.at() also works on strings, TypedArrays, and any array-like that supports it — so "hello".at(-1) gives "o" the same way [..."hello"].at(-1) would.
arr[-1] doesn't throw, which makes it worse than a normal Python-style error. A TypeError would at least get caught during development. undefined slides through silently and shows up three function calls later as "cannot read property of undefined," far from its real cause..at() doesn't change how positive indices work. arr.at(0) behaves exactly like arr[0]. The method is purely additive — it only adds meaning to negative numbers, nothing else changes.arr[-1] = "x" silently succeeds and creates a real property named "-1" on the array object; it just doesn't participate in .length, iteration, or any array method. It looks like it worked and creates a maintenance landmine.Arrays being "objects with numeric-string keys" is the same underlying fact that makes typeof [] return "object" and makes sparse arrays possible — it's baseline JavaScript object mechanics, not anything array-specific. .at() doesn't change that mechanic; it's a purpose-built escape hatch layered on top so common negative-indexing code doesn't have to keep rediscovering arr[arr.length - n] by hand.