通过这篇文章你可以理解迭代器和生成器的一些概念和使用方法。如果想更深入的了解我推荐阅读MDN文档关于迭代器和生成器。同时,本篇文章也参考了网上的一些资料。
迭代器
-
迭代器我理解为可控的迭代,而数组等是不可控迭代
-
迭代器是一个对象
-
必须有一个next()方法,通过 next() 方法实现迭代
- 该方法返回一个对象,具有属性:value(序列中的next值)、done(最后一代为true)
- 通过调用该方法迭代,直至迭代器消耗完
function createIterator(item){
var i = 0;
return { // 返回一个迭代器对象
next: function () { //迭代器对象一定有next()方法
var done = (i>item.length);
var value = !done ? item[i++] : undefined;
return { //next()方法返回结果对象
value: value,
done: done
}
}
}
}
var it = createIterator([10, 2, 3, 4, 5]);
console.log(it.next().value); // 10
...
console.log(it.next().value); // 5
console.log(it.next().value); // undefined
- ES6中为迭代器提供了统一的访问机制
for...of
,当使用for...of
迭代可迭代对象时(Array、Set、Map和String),js引擎就会调用其Symbol.iterator
属性上的方法,从而返回相应的默认迭代器。可以手动获取一下:
var arr = [10, 2, 3, 5];
// 默认迭代器对象
var it = arr[Symbol.iterator]();
- 由此可得,只要在自定义迭代器对象添加
Symbol.iterator
属性,就可以作为一个规范的迭代器使用for...of
进行迭代。
...
return {
[Symbol.iterator]: function () { return this; },
next: function () {
...
var it = createIterator([10, 2, 3, 4, 5]);
for(var v of it){ // 使用迭代器的循环机制遍历
console.log(v);
}
- 可以用
Symbol.iterator
来检测对象是否为可迭代对象:
function isIterator(obj) {
// return typeof obj[Symbol.iterator] === "function"; // 这种方法也可以选用
return Object.prototype.toString.call( obj[Symbol.iterator] )
=== "[object Function]";
}
生成器:
- 生成器是一种返回迭代器的函数,通过
function
关键字后的星号(*)来表示,函数中会用到新的关键字yield
。 - 简化迭代器的创建过程,每遇到 yield 语句表示本次迭代完成,并且返回的对象中 value 为 yield 语句后的值。
- 可以直接使用 for…of 进行迭代
function *createIterator(item) {
for(let i=0; i<item.length; i++){
yield item[i];
}
}
var it = createIterator([10, 2, 4, 5, 6]); // 生成器函数执行返回一个新的迭代器实例it
// 调用迭代器it的next()方法
console.log(it.next()); // {value: 10, done: false}
...
console.log(it.next()); // {value: 6, done: false}
console.log(it.next()); // {value: undefined, done: true}
- next() 可以传递参数,将替换上一次 yield 语句返回的值
// 生成器
function *createIterator() {
var first = yield 2;
var second = yield first * 3;
yield second + 3;
}
// 创建迭代器实例
var it = createIterator();
// 启动迭代器
it.next(); // {value: 2, done: false}
it.next(4); // {value: 12, done: false}
it.next(7); // {value: 10, done: false}
it.next(); // {value: undefined, done: true}
完结
——"Learning is the accumulation of experience, and ability is hard-working patience."