迭代器 iterator
-
迭代
- 从一个数据集合中按照一定的顺序,不断的取出数据的过程
-
迭代与遍历的区别
- 迭代强调的是依次取出,不能确定取出的有多少,也不能保证把数据全部取完
-
迭代器
-
对迭代过程的封装,通常为对象,不同的语言中,表现出来的迭代形式不一样
-
特点
-
迭代器有得到下一个数据的能力
-
判断是否有后续数据的能力
-
数组存储的数据是有限的,迭代器只关心下一个
-
-
-
迭代模式
- 一种设计模式,用于统一迭代的过程,并且规范迭代器的规格
-
js中的迭代器
-
js规定,如果一个对象有next方法,并且返回一个对象,就认为这个对象为迭代器
-
模拟
-
const arr = [1, 2, 3, 4, 5];
const iterator = {
i: 0,
next() {
var result = {
value: arr[this.i],
done: this.i >= arr.length,
}
this.i++;
return result;
}
}
let iter = iterator.next();
while (iter.done) {
console.log(iter.value);
iter = iterator.next();
}
console.log("迭代完成");
在es6中,如果对象具有知名符号属性Symbol.iterator,则表示对象可以迭代
可迭代的对象
- for of循环,专门用来遍历课迭代的对象的(包括数组,类数组),不是可迭代的对象不能使用for of遍历
let list = [10, 20, 30];
let str = "你好呀";
let mymap = new Map();
mymap.set("JS", "Javascript");
mymap.set("PL", "Perl");
mymap.set("PY", "Python");
for (let val of list) {
console.log(val);
/*
* 10
* 20
* 30
*/
}
for (let val of str) {
console.log(val);
/*
* 你
* 好
* 呀
*/
}
for (let [key, val] of mymap) {
console.log(key, val);
/*
* JS Javascript
* PL Perl
* PY Python
*/
}
let it = mymap.values(); //拿到键值
let tmp;
while ((tmp = it.next())) {
if (tmp.done) break;
// console.log(tmp.value, tmp.done);
/*
* Javascript false
* Perl false
* Python false
*/
console.log(tmp);
/*
* {value: "Javascript", done: false}
* {value: "Perl", done: false}
* {value: "Python", done: false}
*/
}
制作一个可迭代对象
// 制作一个可迭代的对象
class Player {
constructor(list) {
this.list = list;
}
[Symbol.iterator]() {
let current = 0; //相当于索引
let that = this;
return {
next() {
return current < that.list.length
? { value: that.list[current++], done: false }
: { done: true };
},
};
}
}
let player = new Player(["Curry", "Harden", "LeBron"]);
for (let tmp of player) {
console.log(tmp);
/*
* Curry
* Harden
* LeBron
*/
}
生成器 generator
-
生成器
- 生成器就是通过构造函数Generator创建出来的对象,生成器既是一个迭代器,同时又是一个可迭代的对象
-
创建生成器
- 只需要把函数Generator对象,加*号
function *test(){} // 或者 function* test(){}
-
生成器的内部执行
-
关键字yield,只能在函数内部使用,表示产生一个迭代数据
-
每一次调用生成器的next方法,会将生成器函数运行到下一个yield关键字位置
-
function *test(){
console.log(123);
}
const gener = test();
gener.next(); // 123
function* test() {
console.log(1);
yield 1;
console.log(2);
yield 2;
console.log(3);
yield 3;
}
const gener = test();
console.log(gener.next()); // 1 {value: 1, done: false}
console.log(gener.next()); // 2 {value: 2, done: false}
console.log(gener.next()); // 3 {value: 3, done: false}
console.log(gener.next()); // {value: undefined, done: true}
创建一个倒向输出迭代器
function* countdown(begin) {
while (begin > 0) {
yield begin--;
}
}
for (let tem of countdown(5)) {
console.log(tem);
/*
* 5
* 4
* 3
* 2
* 1
*/
}
迭代器和生成器的区别
-
生成器是生成元素的,迭代器是访问集合元素的一中方式
-
迭代输出生成器的内容
-
迭代器是一种支持next()操作的对象
-
迭代器(iterator):其中iterator对象表示的是一个数据流,可以把它看做一个有序序列,但我们不能提前知道序列的长度,只有通过nex()函数实现需要计算的下一个数据。可以看做生成器的一个子集。