信息发布→ 登录 注册 退出

什么是javascript的可迭代协议_如何让对象可迭代?

发布时间:2026-01-04

点击量:
JavaScript的可迭代协议是对象需拥有[Symbol.iterator]方法并返回符合迭代器协议的对象;该方法必须为普通函数,返回含next()且返回{value,done}的对象。

JavaScript 的可迭代协议到底是什么?

可迭代协议不是语法糖,也不是新特性,而是 JavaScript 引擎识别“能被 for...ofArray.from()、展开运算符 [...obj] 等消费”的一套约定:对象必须有名为 [Symbol.iterator] 的方法,且该方法返回一个符合迭代器协议的对象(即有 next() 方法,返回 { value, done } 形状的对象)。

让普通对象支持 for...of 的最简写法

直接在对象上定义 [Symbol.iterator] 方法即可。注意:不能用箭头函数(会丢失 this 绑定),且返回值必须是迭代器对象。

const obj = {
  a: 1,
  b: 2,
  c: 3,
  [Symbol.iterator]() {
    const keys = Object.keys(this);
    let index = 0;
    return {
      next() {
        if (index < keys.length) {
          const key = keys[index++];
          return { value: this[key], done: false };
        }
        return { value: undefined, done: true };
      }.bind(this)
    };
  }
};

for (const val of obj) {
  console.log(val); // 1, 2, 3
}
  • [Symbol.iterator] 是固定键名,必须用方括号计算属性写法
  • 迭代器内部的 next() 必须返回 { value, done }done: true 后不可再返回有效值
  • 如果想遍历键名而非值,把 this[key] 换成 key 即可

用生成器函数 function* 简化实现

手写 next() 容易出错,生成器函数自动满足迭代器协议,是最推荐的方式。

const obj = {
  x: 10,
  y: 20,
  z: 30,
  *[Symbol.iterator]() {
    for (const key of Object.keys(this)) {
      yield this[key];
    }
  }
};

console.log([...obj]); // [10, 20, 30]
console.log(Array.from(obj)); // [10, 20, 30]
  • 生成器函数前必须加 *,且内部用 yield 返回每个值
  • 生成器函数体内的 this 指向调用对象,无需手动 bind
  • 不支持 IE,但现代环境(Chrome/Firefox/Safari/Edge)全部支持

常见踩坑点:为什么 for...of 还是报错?

即使加了 [Symbol.iterator],仍可能失败,原因很具体:

  • [Symbol.iterator] 方法抛出异常(比如访问了 undefined 的属性)→ 直接 TypeError: obj is not iterable
  • 返回的不是对象,或对象没有 next 方法 → 同样报 is not iterable
  • 在类实例中定义时,写成了实例属性(如 this[Symbol.iterator] = function(){...}),但没在构造函数里执行,导致原型链上无该方法
  • 使用 Object.assign({}, obj) 后,[Symbol.iterator] 不会被复制(Symbol 属性默认不可枚举,Object.assign 只拷贝可枚举自有属性)

调试时可直接检查:typeof obj[Symbol.iterator] 是否为 "function",再手动调用 obj[Symbol.iterator]().next() 看返回结构是否合规。

标签:# javascript  # java  # edge  # safari  # 为什么  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!