Array.prototype.values()
Returns an iterator that yields each element of the array in order.
values()- Added in JavaScript ECMAScript 2015
Return value
Array IteratorA new iterable iterator object yielding the value at each index of the array.
Errors
Throws a TypeError only if called on null or undefined.
values() returns the array's default iterator — Array.prototype.values === Array.prototype[Symbol.iterator] is true. That is why for...of, spreading and destructuring all work on arrays in the first place, and it means calling values() explicitly is rarely necessary for plain iteration.
When to reach for it
Call it when you want the iterator object rather than the loop: driving next() by hand, consuming part of a sequence and resuming later, or passing an iterator to something that accepts one. It is also handy to make the iteration protocol explicit when a function takes either an array or an iterator.
What trips people up
- It is single-use. After a
for...ofruns to completion, the same iterator yields nothing on a second pass. Breaking out early is different — the iterator keeps its position and a later loop resumes from there. - It holds a reference to the array, not a snapshot, so writes made during iteration are observed.
- Empty slots are yielded as
undefined, so a sparse array iterates dense. values()yields elements, not[index, value]pairs — that is entries().
Example
When to use it
- Pull items one at a time with next() instead of consuming the whole array.
- Process a prefix of a list, break, then resume from the same position later.
- Pass an explicit iterator to a function that accepts any iterable.
- Iterate a sparse array with holes surfaced as undefined.
Frequently asked questions
What is the difference between values() and just using for...of?
There is none for a simple loop: for...of already calls the array's default iterator, which is values(). Call values() explicitly only when you need the iterator object itself, for example to drive next() manually or to resume iteration later.
Why is my array iterator empty the second time?
Array iterators are single-use, so once one is exhausted it always reports done: true. Call values() again for a fresh iterator, or spread it into an array if you need to traverse more than once.
Does values() copy the array?
No, it keeps a reference to the array, so changes made while iterating are visible to subsequent next() calls. Spread it into a new array first if you need a stable snapshot.
More examples
Pausing and resuming with break
Breaking out stops the loop without exhausting the iterator, so the second loop picks up at "c". Had the first loop run to the end, the second would print nothing.
const it = ["a", "b", "c", "d", "e"].values();
for (const v of it) {
console.log("first pass", v);
if (v === "b") break;
}
for (const v of it) {
console.log("second pass", v);
}The iterator tracks the live array
The iterator stores the array and a cursor, not a copy, so the edit at index 1 is visible. Truncating length ends the iteration immediately with done: true.
const arr = ["a", "b", "c"];
const it = arr.values();
console.log(it.next().value);
arr[1] = "CHANGED";
console.log(it.next().value);
arr.length = 2;
console.log(it.next());Manual consumption
Because values() is the default iterator, the same function works on arrays, strings and Sets without any special casing — each yields its first two elements.
function takeTwo(iterable) {
const it = iterable[Symbol.iterator]();
return [it.next().value, it.next().value];
}
console.log(takeTwo([10, 20, 30, 40]));
console.log(takeTwo("hello"));
console.log(takeTwo(new Set([1, 1, 2, 3])));
Discussion