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:
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
- Let keyResult be the result of performing ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, iterate).
- 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.