Короче, потому что в спецификации так сказано. См. Семантика времени выполнения: ForIn / OfHeadEvaluation . Когда exprValue
является объектом, который повторяется (например, someStorage
в for(let v of someStorage)
, он запускается:
d. Return? GetIterator (exprValue, iteratorHint).
Где GetIterator , в случае for..of
:
б. В противном случае установите метод равным? GetMethod (obj, @@ iterator).
4 Позволить итератору быть? Вызов (метод, объект).
5 Если Тип (итератор) не является объектом, выдается исключение TypeError.
Где @@iterator
Symbol.iterator
, на языке spe c.
Итак, someStorage
должен иметь метод Symbol.iterator
, иначе итерация с использованием for..of
не будет Возможно просто вернуть объект из функции.
Это сработало бы, если бы вы создали объект со свойством Symbol.iterator
:
function someFunction() {
let n = 0;
return {
next() {
n++;
if (n <= 5) {
return {
value: n * n,
done: false
}
}
return {
value: undefined,
done: true
}
}
};
}
const someIterableObject = { [Symbol.iterator]: someFunction };
for (let v of someIterableObject) {
console.log(v);
}
Вы также можете значительно упростить ситуацию, используя вместо этого генератор:
function *someFunction() {
let n = 1;
while (n <= 5) {
yield n ** 2;
n++;
}
}
const someIterableObject = { [Symbol.iterator]: someFunction };
for (let v of someIterableObject) {
console.log(v);
}