生成器方法
第八章介绍了生成器,你已学会如何在对象字面量上定义一个生成器:只要在方法名称前附加一个星号(*
)。这一语法对类同样有效,允许将任何方法变为一个生成器。此处有个范例:
class MyClass {
*createIterator() {
yield 1;
yield 2;
yield 3;
}
}
let instance = new MyClass();
let iterator = instance.createIterator();
此代码创建了一个拥有 createIterator()
生成器的 MyClass
类。该方法返回了一个迭代器,它的值在生成器内部用硬编码提供。当你使用一个对象来表示值的集合、并要求能简单迭代这些值,那么生成器方法就非常有用。数组、Set
与 Map
都拥有多个生成器方法,负责让开发者用多种方式来操作它们的项。
既然生成器方法很有用,那么在表示集合的自定义类中定义一个默认迭代器,那就更好。你可以使用 Symbol.iterator
来定义生成器方法,从而定义出类的默认迭代器,就像这样:
class Collection {
constructor() {
this.items = [];
}
*[Symbol.iterator]() {
yield *this.items.values();
}
}
var collection = new Collection();
collection.items.push(1);
collection.items.push(2);
collection.items.push(3);
for (let x of collection) {
console.log(x);
}
// Output:
// 1
// 2
// 3
此例为生成器方法使用了一个需计算名称,并将此方法委托到 this.items
数组的 values()
迭代器上。任意管理集合的类都包含一个默认迭代器,这是因为一些集合专用的操作都要求目标集合具有迭代器。现在,Collection
的任意实例都可以在 for-of
循环内被直接使用,也能配合扩展运算符使用。
当你想让方法与访问器属性在对象实例上出现时,把它们添加到类的原型上就会对此目的有帮助。而另一方面,若想让方法与访问器属性只存在于类自身,那么你就需要使用静态成员。