ES6 Iterator, generator and yield
Opened this issue · 0 comments
nonocast commented
先来复习一下for..in和for..of, 简单来说, for..in在ES5中定义,for..of则是在ES6定义, for..in是遍历对象属性, for..of是遍历对象元素, for..of就用到了Iterator。
let items = ['foo', 'bar'];
for (let item of items) {
debug(item);
}
从iterator角度来看一下for..of干了什么,
let it = items[Symbol.iterator]();
debug(it.next()); // { value: "foo", done: false }
debug(it.next()); // { value: "bar", done: false }
debug(it.next()); // { value: undefined, done: true }
用while实现如下:
let it = items[Symbol.iterator]();
let item = null;
while (!(item = it.next()).done) {
debug(item.value);
}
我们可以通过Symbol.iterator来检查对象是否支持iterator,
let isIterable = obj => { return typeof obj[Symbol.iterator] === 'function'; }
isIterable([1, 2, 3]).should.be.true;
isIterable('hello').should.be.true;
isIterable(new Map()).should.be.true;
isIterable(new Set()).should.be.true;
isIterable({}).should.be.false;
isIterable(7).should.be.false;
这里需要值得注意的是,it是不可逆, 一次性的"玩意"。items[Symbol.iterator]
是一个创建iterator的function, 可以理解为一个生成器,每次需要时即时生成一个新的iterator, 用完也就丢了, 因为再怎么调用都是返回{ value: undefined, done: true }而已。
由此可见:
- array作为"provider"在对象上提供了一个方法支持创建iterator
- 这个创建迭代器的方法称之为generator
- for..of作为"consumer"使用iterator进行迭代
- 所以完成for..of就同时需要iterator和generator的配合
- 而iterator之所以next()每次可以返回不同的值,其中关键就是内部通过yield实现的
现在我们就可以通过generator和yield来亲自DIY下,
function* createIterator() {
while (true) { yield 1; }
}
let it = createIterator();
it.next().value.should.eq(1);
it.next().value.should.eq(1);
it.next().value.should.eq(1);
May it helps.
参考阅读: