Skip to content

对象为什么会报 is not iterable

这个报错通常表示:代码正在把一个值当成“可迭代对象”使用,但这个值并没有实现迭代协议。

什么情况下会触发

最常见的是数组解构、for...of、展开运算符这类场景:

js
const [a, b] = {
  a: 3,
  b: 4,
}

这里会报错,因为右侧是普通对象,不是可迭代对象。

为什么普通对象不行

可迭代对象需要实现 Symbol.iterator

js
const iterable = {
  [Symbol.iterator]() {
    return {
      next() {
        return { done: true }
      },
    }
  },
}

而普通对象默认没有这个接口,所以不能直接用于:

  • 数组解构
  • for...of
  • ...obj 这种基于迭代的展开

正确写法是什么

如果目标只是取对象字段,应该使用对象解构,而不是数组解构:

js
const { a, b } = {
  a: 3,
  b: 4,
}

console.log(a, b) // 3 4

不要去改 Object.prototype[Symbol.iterator]

有些题解会给出这种写法:

js
Object.prototype[Symbol.iterator] = function* () {
  yield* Object.values(this)
}

这不适合作为正常方案,因为它会:

  • 污染全局对象原型
  • 改变所有普通对象的行为
  • 带来难排查的兼容性问题

这类写法最多只能当作“解释协议机制”的实验代码,不适合业务代码。

使用建议

  • 看到 is not iterable,先确认当前值是不是数组、字符串、Set、Map 这类内建 iterable。
  • 普通对象取字段时,用对象解构。
  • 不要为了通过一道题去修改 Object.prototype

基于 MIT 许可发布