这篇文章看几个生成器的例子,便于更好的理解生成器如何使用。
1)遍历对象属性,这个在迭代器的时候给出过,这次用生成器重写一下
function* objectEntries(obj) {
let propKeys = Object.getOwnPropertyNames(obj);
for (let propKey of propKeys) {
yield [propKey, obj[propKey]];
}
}
let jane = { first: 'Jane', last: 'Doe' };
for (let [key,value] of objectEntries(jane)) {
console.log(`${key}: ${value}`);
}
2)获取迭代器的前N个数
function* take(n, iterable) {
for (let x of iterable) {
if (n <= 0) return;
n--;
yield x;
}
}
let arr = ['a', 'b', 'c', 'd'];
for (let x of take(2, arr)) {
console.log(x);
}
还可以利用上面的take函数把无限的生成器转换成有限的:
function* naturalNumbers() {
for (let n=0;; n++) {
yield n;
}
}
for (let x of take(3, naturalNumbers())) {
console.log(x);
}
3)仿数组中的map函数
function* map(iterable, mapFunc) {
for (let x of iterable) {
yield mapFunc(x);
}
}
[...take(4, map(naturalNumbers(), x => x * x))]
4)仿数组的filter函数
function* filter(iterable, filterFunc) {
for (let x of iterable) {
if (filterFunc(x)) {
yield x;
}
}
}
[...take(4, filter(naturalNumbers(), x => (x % 2) === 0))]
5)二叉树遍历
class BinaryTree {
constructor(value, left=null, right=null) {
this.value = value;
this.left = left;
this.right = right;
}
/** Prefix iteration */
* [Symbol.iterator]() {
yield this.value;
if (this.left) {
yield* this.left;
}
if (this.right) {
yield* this.right;
}
}
}
let tree = new BinaryTree('a',
new BinaryTree('b',
new BinaryTree('c'),
new BinaryTree('d')),
new BinaryTree('e')
);
for (let x of tree) {
console.log(x);
}
*以上全部代码在Chrome 48下通过测试