How does `for..of` loop resolve the iterator from an object?

后端 未结 2 1106
太阳男子
太阳男子 2021-01-19 17:35

For an object to implement iterable interface it must implement [Symbol.iterator] key that points to a function that returns the iterator. I\'m won

2条回答
  •  北荒
    北荒 (楼主)
    2021-01-19 18:23

    An object can define only one symbol Symbol.iterator, which is the one that will be called on iteration on the object itself. The other properties of the object, such as the examples you have given (entries, keys, values) may also return an iterator, but those are in general not the same iterators. They could be the same, but that is just an implementation choice. There is no ambiguity as to which iterator is called when iterating the object with for..of. It is the one returned by [Symbol.iterator].

    1. How iterator is obtained from an object?

    You can get it by calling the function keyed with Symbol.iterator, e.g.

    const iterator = obj[Symbol.iterator]();
    

    It is retrieved implicitly with for..of.

    1. Where is it specified in the spec?

    This table in the specs explains:

    @@iterator "Symbol.iterator"

    A method that returns the default Iterator for an object. Called by the semantics of the for-of statement.

    Here is how you can make a custom function for returning the default iterator for an object (overwriting the default one), and see how it gets called:

    const obj = {
        // Define a custom function for returning the default iterator for this object
        [Symbol.iterator]: function () {
            console.log('The iterator-returning function got invoked');
            // Return an iterator from some other object
            //  (but we could have created one from scratch as well):
            return 'abc'[Symbol.iterator]();
        },
        myMethod: function () {
            // This method happens to return the same iterator
            return this[Symbol.iterator]();
        },
        myOtherMethod: function () {
            // This method happens to return another iterator
            return 'def'[Symbol.iterator]();
        }
    }
    
    for (const a of obj) {
        console.log(a); // a b c
    }
    for (const a of obj.myMethod()) {
        console.log(a); // a b c
    }
    for (const a of obj.myOtherMethod()) {
        console.log(a); // d e f
    }
    .as-console-wrapper { max-height: 100% !important; top: 0; }

提交回复
热议问题