如何让JavaScript中的Group类成为可迭代对象(不直接复用数组迭代器)
让Group类实现自定义可迭代性
问题背景
现有如下Group类代码:
class Group { constructor() { this.group = []; } add(input) { if (!this.group.includes(input)) { this.group.push(input); } } static from(arr) { const group = new Group(); for (let el of arr) { group.add(el); } this.group = group; return group; } has(elem) { return this.group.includes(elem); } delete(elem) { let newarr = this.group.filter((n) => n !== elem); this.group = newarr; } }
需要让该类支持for...of遍历,实现如下效果:
for (let value of Group.from(["a", "b", "c"])) { console.log(value); } // → a // → b // → c
注意:不能直接复用数组的Symbol.iterator迭代器
解决方案
要让类成为可迭代对象,需在类中实现[Symbol.iterator]()方法,返回一个自定义迭代器对象(包含next()方法,每次调用返回{ value: 元素值, done: 是否遍历完成 })。
修改后的完整代码:
class Group { constructor() { this.group = []; } add(input) { if (!this.group.includes(input)) { this.group.push(input); } } static from(arr) { const group = new Group(); for (let el of arr) { group.add(el); } return group; } has(elem) { return this.group.includes(elem); } delete(elem) { this.group = this.group.filter((n) => n !== elem); } // 自定义迭代器实现 [Symbol.iterator]() { let currentIndex = 0; // 缓存当前实例的元素数组,避免迭代中数组被修改影响遍历 const elements = [...this.group]; return { next() { if (currentIndex < elements.length) { return { value: elements[currentIndex++], done: false }; } return { done: true }; } }; } }
关键说明
[Symbol.iterator]()方法:这是ES6规定的可迭代对象的核心方法,for...of会自动调用它获取迭代器。- 自定义迭代器逻辑:
- 用
currentIndex维护当前遍历的位置 - 缓存
elements数组,防止迭代过程中调用add/delete修改原数组导致遍历异常 next()方法每次返回当前元素和遍历状态,直到所有元素遍历完成
- 用
- 测试验证:运行目标代码会按顺序输出
a、b、c,符合需求
内容的提问来源于stack exchange,提问作者VOZ ESTOICA
相关产品推荐
相关产品推荐

