Array.prototype.pop()

Removes the last element from an array and returns it, shortening the array by one.

Signature
pop()
  • Added in JavaScript ES3

Return value

anyThe removed element from the array; undefined if the array is empty.

Errors

Throws a TypeError when called on a frozen array or when the length property is not writable in strict mode.

Changelog

  • PHP ES3Introduced on Array.prototype.

pop() takes the last element off an array, returns it, and decrements length. It mutates the array. On an empty array it returns undefined and leaves the length at 0 rather than throwing.

When to reach for it

Use it with push() to run an array as a stack: undo histories, depth-first traversal frontiers, expression evaluators, breadcrumb trails. Removing from the end is cheap because nothing has to shift, so a push/pop worklist stays fast even at large sizes — unlike shift(), which reindexes the whole array.

It is also the concise way to consume a value and shrink the array in one expression: const last = queue.pop().

What trips people up

The undefined return is ambiguous. If the array can legitimately contain undefined, you cannot tell an empty array from a popped undefined; test length before popping in a while loop.

Because it mutates, popping an array a caller passed in silently damages their data. Use arr.at(-1) to read the last element without removing it, or arr.slice(0, -1) to get a shortened copy.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Implement an undo stack where the newest action is reverted first
  • Drive a depth-first traversal using an array as the frontier
  • Take the last segment off a path or breadcrumb array
  • Drain a worklist efficiently without reindexing the array

Frequently asked questions

What does pop() return on an empty array?

It returns undefined and leaves the length at 0 without throwing, so check arr.length first if the array may legitimately contain undefined values.

How do I get the last element without removing it?

Use arr.at(-1), or arr[arr.length - 1] on older engines; both read the value while leaving the array unchanged, unlike pop().

Is pop() faster than shift()?

Yes. pop() removes from the end and only decrements length, while shift() must reindex every remaining element, making it linear in the array size.

More examples

Depth-first traversal with a stack

Because pop() takes from the end, the most recently discovered child is explored first, giving depth-first order. Swapping pop() for shift() would turn the same code into a breadth-first walk.

Example · javascript
const tree = { v: 1, kids: [{ v: 2, kids: [] }, { v: 3, kids: [{ v: 4, kids: [] }] }] };

const frontier = [tree];
const order = [];
while (frontier.length) {
  const node = frontier.pop();
  order.push(node.v);
  frontier.push(...node.kids);
}

console.log(order.join(" -> ")); // 1 -> 3 -> 4 -> 2

Reading the last element without removing it

at(-1) and slice(0, -1) give the last element and the shortened list without touching the source. Reach for them whenever the array belongs to a caller and must not change.

Example · javascript
const path = ["src", "lib", "index.js"];

console.log(path.at(-1));        // 'index.js' — peek, no mutation
console.log(path.length);        // 3

const withoutLast = path.slice(0, -1);
console.log(withoutLast);        // ['src','lib']
console.log(path.length);        // 3 — still intact

Guarding against the ambiguous undefined

The first and third calls both return undefined for entirely different reasons. Only the length check distinguishes an exhausted array from one holding a genuine undefined value.

Example · javascript
const values = [1, undefined];

console.log(values.pop()); // undefined — a real element
console.log(values.pop()); // 1
console.log(values.pop()); // undefined — now the array is empty
console.log(values.length); // 0

// Length is the reliable signal.
console.log(values.length > 0 ? values.pop() : "empty"); // 'empty'

Discussion

  • Be the first to comment on this lesson.