Spec-Zone.ru › JavaScript

TypeError: 'x' is not iterable

Исключение JavaScript "is not iterable" возникает, когда значение, которое распределяется в массив или вызов функции, предоставляется как правая часть for...of, как аргумент функции, такой как Promise.all или Set(), или как правая часть деструктуризации массива, не является итерируемым объектом. Эта ошибка также возникает, когда Array.fromAsync() или for await...of используется с неасинхронным итерируемым объектом.

Сообщение

TypeError: Spread syntax requires ...iterable[Symbol.iterator] to be a function (V8-based & Safari)
TypeError: %Array%.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function (V8-based & Safari)
TypeError: Array.fromAsync requires that the property of the first argument, items[Symbol.asyncIterator], when exists, be a function (V8-based & Safari)
TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator)) (V8-based)
TypeError: x is not async iterable (V8-based)
TypeError: x is not iterable (V8-based & Firefox)
TypeError: undefined is not a function (near '...y of x...') (Safari)
TypeError: Array.from: no function (Safari)
TypeError: Type error (Safari)

Тип ошибки

TypeError

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

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

const nonIterable1 = {};
const nonIterable2 = { [Symbol.iterator]: 1 };

[...nonIterable1];
Math.max(...nonIterable1);
for (const x of nonIterable1);
new Set(nonIterable1);
Array.from(nonIterable2);
new Int8Array(nonIterable2);
const [] = nonIterable1;

Примеры

Деструктуризация неитерируемого массива

const myObj = { arrayOrObjProp1: {}, arrayOrObjProp2: [42] };

const {
  arrayOrObjProp1: [value1],
  arrayOrObjProp2: [value2],
} = myObj; // TypeError: object is not iterable

console.log(value1, value2);

Неитерируемый объект может оказаться undefined в некоторых средах выполнения.

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

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

const obj = { France: "Paris", England: "London" };
for (const p of obj) {
  // …
} // TypeError: obj is not iterable

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

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

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

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

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

for (const capital of map.values()) {
  console.log(capital);
}

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

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

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

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

for (const x of generate) {
  console.log(x);
} // TypeError: generate is not iterable

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

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

for (const x of generate(1, 2)) {
  console.log(x);
}

Итерация по пользовательскому итерируемому объекту

Пользовательские итерируемые объекты могут быть созданы путем реализации метода Symbol.iterator. Вы должны быть уверены, что ваш метод итератора возвращает объект, который является итератором, то есть он должен иметь метод next.

const myEmptyIterable = {
  [Symbol.iterator]() {
    return []; // [] is iterable, but it is not an iterator — it has no next method.
  },
};

Array.from(myEmptyIterable); // TypeError: myEmptyIterable is not iterable

Вот корректная реализация:

const myEmptyIterable = {
  [Symbol.iterator]() {
    return [][Symbol.iterator]();
  },
};

Array.from(myEmptyIterable); // []

См. также

  • Протокол итерации
  • Object.keys
  • Object.entries
  • Map
  • Функции-генераторы
  • for...of

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/is_not_iterable

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API