Stage 1 Draft / February 5, 2025

Range proposal

27 Control Abstraction Objects

27.1 Iteration

27.1.3 Iterator Objects

27.1.3.2 Properties of the Iterator Constructor

27.1.3.2.2 Iterator.range ( start, end, optionOrStep )

  1. If start is a Number, return ? CreateNumericRangeIterator(start, end, optionOrStep, number-range).
  2. If start is a BigInt, return ? CreateNumericRangeIterator(start, end, optionOrStep, bigint-range).
  3. Throw a TypeError exception.

27.1.4 The NumericRangeIterator Object

A NumericRangeIterator object is an iterator that yields numbers. There is not a named constructor for NumericRangeIterator objects. Instead, NumericRangeIterator objects are created by the CreateNumericRangeIterator abstract operation as needed.

27.1.4.1 CreateNumericRangeIterator ( start, end, optionOrStep, type )

The abstract operation CreateNumericRangeIterator takes arguments start (a Number or a BigInt), end (an ECMAScript language value), optionOrStep (an ECMAScript language value), and type (number-range or bigint-range) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. If start is NaN, throw a RangeError exception.
  2. If end is NaN, throw a RangeError exception.
  3. If type is number-range, then
    1. Assert: start is a Number.
    2. If end is not a Number, throw a TypeError exception.
    3. Let zero be +0𝔽.
    4. Let one be 1𝔽.
  4. Else,
    1. Assert: start is a BigInt. Editor's Note
      Allowing all kinds of number (bigint, decimals, ...) to range from a finite number to infinity.
    2. If end is not +∞𝔽 or -∞𝔽 and end is not a BigInt, throw a TypeError exception.
    3. Let zero be 0.
    4. Let one be 1.
  5. If start is +∞𝔽 or -∞𝔽, throw a RangeError exception.
  6. Let inclusiveEnd be false.
  7. If optionOrStep is undefined or null, then
    1. Let step be undefined.
  8. Else if optionOrStep is an Object, then
    1. Let step be ? Get(optionOrStep, "step").
    2. Set inclusiveEnd to ToBoolean(? Get(optionOrStep, "inclusive")).
  9. Else if type is number-range and optionOrStep is a Number, then
    1. Let step be optionOrStep.
  10. Else if type is bigint-range and optionOrStep is a BigInt, then
    1. Let step be optionOrStep.
  11. Else,
    1. Throw a TypeError exception.
  12. If step is undefined or null, then
    1. If end is +∞𝔽, let step be one.
    2. Else if end is -∞𝔽, let step be -one.
    3. Assert: In the next branch, end is a BigInt and start is a BigInt, or end is a Number and start is a Number.
    4. Else if end > start, let step be one.
    5. Else let step be -one.
  13. If step is NaN, throw a RangeError exception.
  14. If type is number-range and step is not a Number, throw a TypeError exception.
  15. Else if type is bigint-range and step is not a BigInt, throw a TypeError exception.
  16. If step is +∞𝔽 or -∞𝔽, throw a RangeError exception.
  17. If step is zero and start is not end, throw a RangeError exception.
  18. Let closure be a new Abstract Closure with no parameters that captures start, end, step, inclusiveEnd, zero, one and performs the following steps when called:
    1. If end is +∞𝔽, let ifIncrease be true.
    2. Else if end is -∞𝔽, let ifIncrease be false.
    3. Assert: In the next branch, end is a BigInt and start is a BigInt, or end is a Number and start is a Number.
    4. Else if end > start, let ifIncrease be true.
    5. Else let ifIncrease be false.
    6. If step > zero, let ifStepIncrease be true.
    7. Else let ifStepIncrease be false.
    8. If ifIncrease is not ifStepIncrease, return undefined.
    9. Let hitsEnd be false.
    10. Let currentCount be zero.
    11. NOTE: You can debug these steps at https://tc39.es/proposal-Number.range/playground.html .
    12. Repeat, while hitsEnd is false,
      1. Let currentYieldingValue be start + (step * currentCount).
      2. If currentYieldingValue is end, Set hitsEnd to true.
      3. Set currentCount to currentCount + one.
      4. If ifIncrease is true, then
        1. Assert: end is a BigInt or +∞𝔽 and currentYieldingValue is a BigInt, or end is a Number and currentYieldingValue is a Number.
        2. If end is not +∞𝔽, then
          1. If inclusiveEnd is true, then
            1. If currentYieldingValue > end, return undefined.
          2. Else,
            1. If currentYieldingValueend, return undefined.
      5. Else,
        1. Assert: end is a BigInt or -∞𝔽 and currentYieldingValue is a BigInt, or end is a Number and currentYieldingValue is a Number.
        2. If end is not -∞𝔽, then
          1. If inclusiveEnd is true, then
            1. If end > currentYieldingValue, return undefined.
          2. Else,
            1. If endcurrentYieldingValue, return undefined.
      6. Perform ? Yield(currentYieldingValue).
    13. Return undefined.
  19. Return CreateIteratorFromClosure(closure, "%NumericRangeIteratorPrototype%", %NumericRangeIteratorPrototype%).

27.1.4.2 The %NumericRangeIteratorPrototype% Object

The %NumericRangeIteratorPrototype% object:

  • has properties that are inherited by all NumericRangeIterator Objects.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %IteratorPrototype%.
  • has the following properties:

27.1.4.2.1 %NumericRangeIterator%.next ( )

  1. Return ? GeneratorResume(this value, empty, "%NumericRangeIteratorPrototype%").

27.1.4.2.2 %NumericRangeIteratorPrototype%.[@@toStringTag]

The initial value of the @@toStringTag property is the String value "NumericRangeIterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.