TypeError: 'x' is not iterable (Тип ошибки 'x' не является итерационным)

Сообщение

TypeError: "x" не является итерационным (Firefox, Chrome)
TypeError: 'x' не является функцией или её возвращаемое значение не является итерационным (Chrome)

Тип ошибки

Что пошло не так?

Значение, которое даётся как правая сторона for...of или как аргумент функции, такой как Promise.all или TypedArray.from (en-US), не является итерационным объектом. Повторяемое может быть, встроенный итератор типа, такие как Array, String или Map (en-US), генератор результатом, или объект, реализующий итератор протокол.

Примеры

Итерация по свойствам объекта

В JavaScript, object не повторяется, если они реализуют итерационный протокол . Поэтому нельзя использовать for...of для перебора свойств объекта.

js
var obj = { France: "Paris", England: "London" };
for (let p of obj) {
  // TypeError: obj не является итерационным
  // …
}

Вместо этого вы должны использовать Object.keys или Object.entries, для итерации по свойствам или записям объекта.

js
var obj = { France: "Paris", England: "London" };
// Iterate over the property names:
for (let country of Object.keys(obj)) {
  var capital = obj[country];
  console.log(country, capital);
}

for (const [country, capital] of Object.entries(obj))
  console.log(country, capital);

Другим вариантом для этого варианта использования может быть использование Map (en-US):

js
var map = new Map();
map.set("France", "Paris");
map.set("England", "London");
// Iterate over the property names:
for (let country of map.keys()) {
  let capital = map[country];
  console.log(country, capital);
}

for (let capital of map.values()) console.log(capital);

for (const [country, capital] of map.entries()) console.log(country, capital);

Итерация по генератору

Генераторы - это функции, вызываемые для создания итерационного объекта.

js
function* generate(a, b) {
  yield a;
  yield b;
}

for (let x of generate) // TypeError: генерация не является итерационной
  console.log(x);

Если они не вызываются, то объект Function, соответствующий генератору, можно вызвать, но нельзя выполнить итерацию. Вызов генератора создаёт итерационный объект, который будет выполнять итерацию по значениям, полученным во время выполнения генератора.

js
function* generate(a, b) {
  yield a;
  yield b;
}

for (let x of generate(1, 2)) console.log(x);

Смотрите также