JavaScript自定义迭代器next()方法无法访问存储数据的Array数组问题
问题原因与修复方案
核心错误点
- this指向偏差:你返回的迭代器对象中的
next()是普通函数,调用时this指向该迭代器对象而非Group实例,因此this.values为undefined,读取length属性就会触发报错。 - 你已经在
[Symbol.iterator]作用域内缓存了nvalues = this.values,可以直接通过闭包访问该变量,不需要用this取值。 - 原迭代结束判断逻辑存在边界错误,会漏掉最后一个元素。
修复后可运行代码
class Group { constructor() { this.values = []; } add(value) { if (!this.values.includes(value)) { this.values.push(value); } } delete(value) { if (this.values.includes(value)) { this.values = this.values.filter(e => e !== value); } } has(value) { return this.values.includes(value); } [Symbol.iterator]() { let count = 0; // 这里已经缓存了Group实例的values数组,直接通过闭包使用即可 const nvalues = this.values; return { next() { if (count >= nvalues.length) { return { value: undefined, done: true }; } else { // 简化取值逻辑,先返回当前索引值再自增计数 return { value: nvalues[count++], done: false }; } } } } static from(newValues) { let group = new Group(); for (let value of newValues) { if (!group.has(value)) { group.add(value); } } return group; } } let group = Group.from([1, 2, 3, 4, 3, 2, 1, 5]); console.log(group.values); // 输出 [1,2,3,4,5] for (let value of group) { console.log(value); // 依次输出 1 2 3 4 5 }
补充说明
如果你一定要用this访问values,也可以把next()改成箭头函数绑定外层作用域的this,但直接用已经缓存的nvalues是性能更高、更简洁的方案。
内容的提问来源于stack exchange,提问作者DntMesArnd
相关产品推荐
相关产品推荐

