mozilla
Your Search Results

    iterable

    This is an experimental technology, part of the Harmony (ECMAScript 6) proposal.
    Because this technology's specification has not stabilized, check the compatibility table for usage in various browsers. Also note that the syntax and behavior of an experimental technology is subject to change in future version of browsers as the spec changes.

    The Iterable Interface

    In the strict sense, The Iterable in ECMAScript 6 is an interface (or in other words, a protocol), not a type of object like Array or Map.

    The Iterable interface includes the following property:

    Property value Requirements
    @@iterator A zero arguments function that returns an object. The function returns an object that conforms to the Iterator interface.

    The @@iterator is a specification name for the Well-known Symbol Symbol.iterator.

    Iterable objects

    Any object that implements the Iterable interface is called an iterable object (iterable for short).More specifically, an iterable object has to have a Symbol.iterator keyed property whose value is a function that returns an object that supports the Iterator interface.

    For example, a string is an iterable:

    var aString = "hello"
    typeof aString[Symbol.iterator] // "function"
    aString[Symbol.iterator]() + "" // "[object String Iterator]"
    [...aString]                    // ["h", "e", "l", "l", "o"]
    

    Builtin iterables

    String, Array, Map, Set and Generator objects are all builtin iterables, because the prototype objects of them all have an @@iterator method. e.g., String.prototype.@@iterator, Array.prototype.@@iterator, Generator.prototype.@@iterator and so on.

    The arguments object is also a builtin iterable, but it has a self property @@iterator, not a prototype one.

    User-defined iterables

    We can make our own iterables like this:

    var myIterable = {}
    myIterable[Symbol.iterator] = function* () {
        yield 1;
        yield 2;
        yield 3;
    };
    [...myIterable] // [1, 2, 3]
    

    Builtin APIs need iterables

    Map([iterable]), WeakMap([iterable]), Set([iterable]) and WeakSet([iterable]):

    var myObj = {}
    new Map([[1,"a"],[2,"b"],[3,"c"]]).get(2)               // "b"
    new WeakMap([[{},"a"],[myObj,"b"],[{},"c"]]).get(myObj) // "b"
    new Set([1, 2, 3]).has(3)                               // true
    new Set("123").has("2")                                 // true
    new WeakSet(function*() {
        yield {};
        yield myObj;
        yield {};
    }()).has(myObj)                                     // true
    

    and Promise.all(iterable), Promise.race(iterable), Array.from()

    Syntaxes need iterables

    for-ofspread, yield*, destructing

    for(let value of ["a", "b", "c"]){
        console.log(value)
    }
    // "a"
    // "b"
    // "c"
    
    [..."abc"] // ["a", "b", "c"]
    
    function* gen(){
      yield* ["a", "b", "c"]
    }
    
    gen().next() // { value:"a", done:false }
    
    [a, b, c] = new Set(["a", "b", "c"])
    a // "a"
    
    

    Non-well-formed iterables

    If an iterable's @@iterator method doesn't return an iterator object, then it's a non-well-formed iterable, using it as such is likely to result in runtime exceptions or buggy behavior:

    var nonWellFormedIterable = {}
    nonWellFormedIterable[Symbol.iterator] = () => 1
    [...nonWellFormedIterable] // TypeError: [] is not a function
    

    A generator object is an iterator or an iterable?

    The answer is, both are correct:

    var aGeneratorObject = function*(){
        yield 1;
        yield 2;
        yield 3;
    }()
    typeof aGeneratorObject.next                
    // "function", because it has a next method, so it's an iterator
    typeof aGeneratorObject[Symbol.iterator]    
    // "function", because it has an @@iterator method, so it's an iterable
    aGeneratorObject[Symbol.iterator]() === aGeneratorObject  
    // true, because its @@iterator method return its self (an iterator), so it's an well-formed iterable
    [...aGeneratorObject]                       
    // [1, 2, 3]
    

    Document Tags and Contributors

    Contributors to this page: ziyunfei, lavish, fitzgen, rwaldron, BlindWanderer
    Last updated by: ziyunfei,