Вот как вы можете создать пользовательскую функцию для возврата итератора по умолчанию для объекта (перезаписав его по умолчанию) и посмотреть, как он вызывается:

объект реализовал итеративный интерфейс, он должен реализовать[Symbol.iterator] ключ, который указывает на функцию, которая возвращаетiterator, Мне интересно, еслиfor..of Цикл внутренне вызывает этот метод на объекте, чтобы получить этоiterator?

Мне интересно, что, например,Map определяет интерфейс с несколькими итераторами (записями, значениями, ключами), и кажется, что если не указано явно,for..of цикл использует итератор, возвращаемыйmap.entries() вызов.

Я пытаюсь найтив спецификации но это только указывает, чтоiterator передается в качестве параметра абстрактной операцииForOf:

Абстрактная операция ForIn / OfBodyEvaluation вызывается с аргументами lhs, stmt,итератор, iterationKind, lhsKind и labelSet.

Итак, в основном два вопроса:

Как итератор получается из объекта?Где это указано в спецификации?
 Bergi10 окт. 2017 г., 13:48
Проверьте последний шагФорин / ИзГоловаоценка
 Max Koretskyi aka Wizard10 окт. 2017 г., 14:03
@ Берги, большое спасибо за подтверждение, я так и думал.
 Bergi10 окт. 2017 г., 13:51
"если не указано явно, цикл for..of использует итератор, возвращаемыйmap.entries() вызов."- не совсем. Он всегда используетmap[Symbol.iterator](), это тот же метод, что иentries хотя, Если вы передаете объект итератор, он вызывает…[Symbol.iterator]() на тех же, просто метод возвращает сам объект (return this;) на экземплярах итераторов.

Ответы на вопрос(2)

Решение Вопроса

7.4.1 GetIterator (obj [, метод]), Это получает@@iterator свойство переданного объекта на шаге 1а. абстрактной операции:

а. Установленметод вGetMethod([email protected]@ iterator).

@@iterator этообщеизвестный символ этоSymbol.iterator собственность на объекты.

Это используется циклами for-in и for-of из-за производств в13.7.5.11 Семантика времени выполнения:

ИнструкцияИтерации : за(ForDeclaration изВыражениеПрисваивания) утверждение

ПозволятьkeyResult быть результатом выполненияФорин / OfHeadEvaluation(BoundNames ofForDeclaration, ВыражениеПрисваиванияитерации).ВернутьФорин / OfBodyEvaluation(ForDeclaration, утверждение, keyResult, iterate, lexicalBinding,labelSet).

Здесь вы можете увидеть аргумент итератора, переданныйФорин / OfBodyEvaluation это возвращаемое значениеkeyResult изФорин / OfHeadEvaluation, Возвращаемое значение на шаге 7b:

б. ВернутьGetIterator(exprValue).

Таким образом, цикл for-of получает итератор, обращаясь к@@iterator или жеSymbol.iterator известный символ по спецификации.

 Max Koretskyi aka Wizard10 окт. 2017 г., 14:13
фантастика, ценю! удачи
 Li35710 окт. 2017 г., 14:00
@ AngularInDepth.com Да. ТолькоexprValue передается.
 Max Koretskyi aka Wizard10 окт. 2017 г., 13:58
Большое спасибо, это то, что я искал.GetIterator ( obj [ , method ] ) может принять метод, а из7b Я вижу, что метод не указан, следовательно,Set method to ? GetMethod(obj, @@iterator)., Верный? Также мне интересно, что это за знак вопроса передGetMethod, Есть идеи?
 Li35710 окт. 2017 г., 14:08
@ AngularInDepth.com Это описано здесь:stackoverflow.com/questions/41733976/...

Symbol.iterator, который будет вызываться на итерации объектасам, Другие свойства объекта, такие как приведенные вами примеры (entries, keys, values) также может возвращать итератор, но в целом это не те же итераторы. Oнимог быть таким же, но это просто выбор реализации. Нет никакой двусмысленности относительно того, какой итератор вызывается при итерации объекта сfor..of, Это тот, который вернулся[Symbol.iterator].

Как итератор получается из объекта?

Вы можете получить его, вызвав функцию с ключомSymbol.iteratorнапример,

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

Получается неявно сfor..of.

Где это указано в спецификации?

Эта таблица в спецификации объясняет:

@@ iterator "Symbol.iterator"

Метод, который возвращает Итератор по умолчанию для объекта. Вызывается семантикойfor-of заявление.

Вот как вы можете создать пользовательскую функцию для возврата итератора по умолчанию для объекта (перезаписав его по умолчанию) и посмотреть, как он вызывается:

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; }

Ваш ответ на вопрос