Iterator.prototype.take()

Limit an iterator to its first n values, making infinite sequences safe to consume.

Signature
take(limit)
  • Added in JavaScript ES2025 (Baseline March 2025)

Parameters

ParameterTypeDescription
$limitnumberThe number of elements to take from the start of the iteration. Converted to an integer; a fractional value is truncated and Infinity is allowed.

Return value

Iterator HelperA new iterator helper object that yields elements from the underlying iterator one by one and completes once limit elements have been yielded, or once the underlying iterator is exhausted, whichever comes first.

Errors

Throws a RangeError if limit is negative or becomes NaN when converted to an integer — which includes calling take() with no argument, since undefined converts to NaN.

take() is the guard rail of the iterator helpers. An infinite generator is only usable if something downstream stops pulling from it, and this is the standard way to say when.

When to reach for it

  • Ending an unbounded sequence so toArray(), spread or for...of terminates.
  • Taking a page of results: src.drop(page * size).take(size).
  • Sampling the head of an expensive pipeline while debugging, without recomputing the whole thing.

What trips people up

Order matters and is not commutative in the way array slicing might suggest. src.drop(2).take(5) yields elements 3–7; src.take(5).drop(2) yields elements 3–5, because the limit is applied to the source first.

The argument is validated eagerly and strictly. take() with no argument, or with a value that converts to NaN, throws a RangeError immediately rather than defaulting to zero or infinity — so does any negative number. And taking more than the source has is not an error: you simply get everything the source had.

Once the limit is reached the helper closes the underlying iterator by calling its return() method, which runs any finally block in a generator.

Example

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

When to use it

  • Take the first ten values from an infinite Fibonacci or ID generator
  • Implement paging over an iterator by combining drop() and take()
  • Cap a potentially huge result set before collecting it into an array

Frequently asked questions

How do I get the first n values of an infinite generator?

Call take(n) on it and then collect: gen().take(n).toArray(). take() bounds the sequence so the collecting step terminates. Without it, toArray() or a spread on an endless generator loops forever and hangs the thread.

Why does take() throw a RangeError?

Because limit converted to an integer was negative or NaN. Calling take() with no argument is the usual cause: undefined becomes NaN. Pass an explicit non-negative number, or Infinity if you genuinely want no limit.

Does take() close the underlying iterator?

Yes. Once it has yielded limit elements it calls return() on the source iterator, which triggers any finally block inside a generator so cleanup runs. The source is then exhausted and cannot be resumed.

More examples

Order of take() and drop()

The two chains are not equivalent: the second one caps the source at five elements before dropping, so only three survive.

Example · javascript
function* naturals() {
  let n = 1;
  while (true) yield n++;
}

// Skip 2, then keep 5.
console.log(naturals().drop(2).take(5).toArray()); // [3, 4, 5, 6, 7]

// Keep 5, then skip 2 of those.
console.log(naturals().take(5).drop(2).toArray()); // [3, 4, 5]

Paging over an iterator

Each call starts a fresh iterator, so pages are independent. The last page is short rather than an error, because take() stops at whichever comes first: the limit or the end of the source.

Example · javascript
const rows = ["r1", "r2", "r3", "r4", "r5", "r6", "r7"];
const pageSize = 2;

function page(n) {
  return rows.values().drop(n * pageSize).take(pageSize).toArray();
}

console.log(page(0)); // ["r1", "r2"]
console.log(page(2)); // ["r5", "r6"]
console.log(page(3)); // ["r7"]  — short final page

Discussion

  • Be the first to comment on this lesson.