Iterator.prototype.drop()
Skip the first n values of an iterator and yield everything after them.
drop(limit)- Added in JavaScript ES2025 (Baseline March 2025)
Parameters
| Parameter | Type | Description |
|---|---|---|
$limit | number | The number of elements to drop from the start of the iteration. Converted to an integer; a fractional value is truncated. |
Return value
Iterator HelperA new iterator helper object that discards the first limit elements of the underlying iterator and then yields the remaining elements one by one; if the source has limit or fewer elements the helper completes immediately.
Errors
Throws a RangeError if limit is negative or becomes NaN when converted to an integer, which includes calling drop() with no argument.
drop() is the offset half of iterator slicing: it throws away a fixed count from the front and passes the rest through. Together with take() it gives you slice(start, end) semantics over any iterator, including ones with no length.
When to reach for it
- Skipping a header line, a preamble, or a sentinel value at the start of a parsed sequence.
- Paging:
src.drop(offset).take(pageSize). - Ignoring a warm-up section of a generated series before sampling it.
What trips people up
The skipping is still lazy, but it is not free — the dropped elements are pulled and discarded when the first next() arrives, so any side effects in the source still happen for them. drop() cannot jump ahead; there is no random access in the iterator protocol.
Dropping more than the source contains is not an error. The helper simply finishes with no values, which reads as an empty result rather than an exception — an easy thing to misdiagnose as a broken pipeline.
Like take(), the argument is validated strictly: negative or NaN counts throw a RangeError rather than being clamped.
Example
When to use it
- Skip the header row of a parsed CSV before processing the data rows
- Offset into a result set to implement page two and beyond
- Discard a fixed warm-up prefix from a generated sequence
Frequently asked questions
How do I slice an iterator like array.slice(2, 5)?
Chain drop() then take(): it.drop(2).take(3) yields the same three elements. Keep the order drop-then-take; take(3).drop(2) caps the source at three elements first and leaves only one.
Is drop() faster than skipping with an index check?
It is about the same in work done but clearer to read. drop() still pulls and discards each skipped element, exactly as a filter on index would, because the iterator protocol has no way to seek. The gain is that the intent is explicit and nothing downstream sees the skipped values.
What happens if I drop more elements than the iterator has?
You get an empty result, not an error. The helper exhausts the source looking for elements to skip, finds no more, and completes immediately with { value: undefined, done: true }.
More examples
Skipping a header row
The header line is discarded before the parsing callback ever sees it, so map() never has to special-case index 0. Output is three objects with numeric scores.
const csv = "name,score\nana,10\nbo,7\ncy,12";
const rows = csv
.split("\n")
.values()
.drop(1) // header
.map((line) => {
const [name, score] = line.split(",");
return { name, score: Number(score) };
})
.toArray();
console.log(rows);Dropped elements still run their side effects
One next() call logs "produced a", "produced b" and "produced c" before returning "c". The generator body still runs for the skipped values — drop() consumes them, it does not skip past them.
function* noisy() {
for (const v of ["a", "b", "c"]) {
console.log("produced", v);
yield v;
}
}
const rest = noisy().drop(2);
console.log("built, nothing produced yet");
console.log(rest.next().value); // "c"
Discussion