为什么自定义迭代器在 for…of 里不生效?

上官慧芳 阅读 19

我写了个对象想用 for…of 遍历,但根本进不去循环,是不是哪里搞错了?

我给对象加了 Symbol.iterator 方法,也 return 了一个带 next 的对象,但就是没效果:

const myObj = {
  data: [1, 2, 3],
  [Symbol.iterator]() {
    let index = 0;
    return {
      next: () => {
        if (index < this.data.length) {
          return { value: this.data[index++], done: false };
        }
        return { done: true };
      }
    };
  }
};

for (const item of myObj) {
  console.log(item); // 根本没输出!
}

奇怪的是,如果我把 iterator 方法写成普通函数再手动调用 .next() 是能拿到值的,但 for…of 就不行,这是为啥?

我来解答 赞 8 收藏
二维码
手机扫码查看
1 条解答
一钧
一钧 Lv1
问题出在 this 上。你用的是箭头函数,箭头函数的 this 是词法绑定的,它不会指向 myObj,而是指向定义时所在的上下文(通常是 windowundefined),所以 this.dataundefined,自然就进不了循环。

你手动调用 .next() 能工作,是因为你可能是在全局作用域下直接调的,但 for...of 内部调用时,箭头函数里的 this 还是没绑定对。

改法很简单,把 next 改成普通函数,或者用变量先把 data 抓出来:

const myObj = {
data: [1, 2, 3],
[Symbol.iterator]() {
const data = this.data;
let index = 0;
return {
next() {
if (index < data.length) {
return { value: data[index++], done: false };
}
return { done: true };
}
};
}
};


或者更简洁点,直接用生成器函数,可读性更高:

const myObj = {
data: [1, 2, 3],
*[Symbol.iterator]() {
for (const item of this.data) {
yield item;
}
}
};


这两种都能让 for...of 正常跑起来。生成器那版是更好的写法,少写不少样板代码,也避免了 this 和箭头函数的坑。
点赞 5
2026-02-26 23:05