Search code examples
javascriptiteratorecmascript-2017for-of-loop

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


For an object to implement iterable interface it must implement [Symbol.iterator] key that points to a function that returns the iterator. I'm wondering if the for..of loop internally calls this method on an object to get that iterator?

The reason I'm curious is that, for example, Map defines an interface with several iterators (entries, values, keys) and it seems that if not specified explicitly the for..of loop uses the iterator returned by map.entries() call.

I've trying searching in the specification but it only specifies that iterator is passed as a parameter to the abstract operation ForOf:

The abstract operation ForIn/OfBodyEvaluation is called with arguments lhs, stmt, iterator, iterationKind, lhsKind, and labelSet.

So basically two questions:

  1. How is iterator obtained from an object?
  2. Where is it specified in the specification?

Solution

  • The specific place where the operation is specified is in 7.4.1 GetIterator( obj [ , method ] ). This gets the @@iterator property of the passed object in step 1a. of the abstract operation:

    a. Set method to GetMethod(obj, @@iterator).

    @@iterator is a well-known symbol that is the Symbol.iterator property on objects.

    This is used by for-in and for-of loops due to the productions in 13.7.5.11 Runtime Semantics:

    IterationStatement : for(ForDeclaration of AssignmentExpression) Statement

    1. Let keyResult be the result of performing ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, iterate).
    2. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexicalBinding, labelSet).

    Here, you can see the iterator argument passed to ForIn/OfBodyEvaluation is the return value keyResult of ForIn/OfHeadEvaluation. The return value is, in step 7b:

    b. Return GetIterator(exprValue).

    Thus, for-of loops get the iterator by accessing the @@iterator or Symbol.iterator well-known symbol by specification.