如何在JavaScript/ES6中用生成器方法创建含值集合的类并实现迭代器
嘿,这两个问题都是ES6迭代器和生成器的基础用法,我来一步步帮你搞定!
一、给Service类添加默认迭代器
要让你的Service实例能用for...of循环遍历,核心就是在类上实现Symbol.iterator方法——这是ES6定义的“可迭代接口”的关键标识。这个方法需要返回一个迭代器对象,也就是带有next()方法的对象,每次调用next()会返回{ value: 当前值, done: 是否遍历结束 }的结构。
最简单的实现:复用数组的迭代器
因为你的link属性是数组,而数组本身已经实现了可迭代接口,所以直接复用它的迭代器就行,代码超简洁:
class Service { constructor() { this.link = []; } // 实现Symbol.iterator方法 [Symbol.iterator]() { // 返回link数组的内置迭代器 return this.link[Symbol.iterator](); } } var service = new Service(); service.link.push(1); service.link.push(2); service.link.push(3); for (let x of service) { console.log(x); // 会依次输出1、2、3 }
手动实现迭代器(进阶)
如果你想自己控制遍历逻辑(比如自定义终止条件、修改返回值),也可以手动写迭代器对象:
class Service { constructor() { this.link = []; this.currentIndex = 0; } [Symbol.iterator]() { // 用箭头函数绑定this,确保next方法里能访问到实例的属性 return { next: () => { if (this.currentIndex < this.link.length) { return { value: this.link[this.currentIndex++], done: false }; } else { this.currentIndex = 0; // 重置索引,方便下次重新遍历 return { done: true }; } } }; } }
二、用生成器方法创建包含值集合的类
ES6的生成器(Generator)是简化迭代器实现的语法糖,用*标记方法,内部用yield关键字返回遍历值,生成器会自动帮你处理迭代器的next()逻辑,写起来更直观。
用生成器实现默认迭代器
你可以直接把Symbol.iterator定义成生成器方法,这样类实例默认就是可迭代的:
class Service { constructor() { this.link = []; } // 生成器版的默认迭代器 *[Symbol.iterator]() { // 遍历link数组,逐个yield值 for (const item of this.link) { yield item; } // 更简洁的写法:用yield*委托给数组的迭代器 // yield* this.link; } // 自定义生成器方法:反向遍历link *reverseIterator() { for (let i = this.link.length - 1; i >= 0; i--) { yield this.link[i]; } } } var service = new Service(); service.link.push(1, 2, 3); // 默认for...of遍历 for (let x of service) { console.log(x); // 1、2、3 } // 用自定义生成器遍历 for (let x of service.reverseIterator()) { console.log(x); // 3、2、1 }
生成器的核心知识点
yield:暂停生成器执行,返回当前值,下次调用next()时从暂停处继续。yield*:委托给另一个可迭代对象(数组、字符串、其他生成器等),自动遍历它的所有值。- 生成器方法返回的是一个生成器对象,它本身就是迭代器,所以可以直接用在
for...of循环里。
这样你的Service类不仅具备了默认的可迭代特性,还能通过生成器轻松扩展各种自定义遍历逻辑~
内容的提问来源于stack exchange,提问作者mlhazan
相关产品推荐
相关产品推荐

