贝利信息

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

日期:2026-01-04 00:00 / 作者:夜晨
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
}

用生成器函数 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]

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

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

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