迭代器和生成器
什么是迭代:
从一个数据集合中按照一定的顺序,不断地取出数据的过程叫做迭代。
迭代和遍历的区别:
迭代针对依次取出,不确定取出的数据是多少,不确定要去除的数据有多少,遍历要知道数据集合的长度,不断的全部取出数据。
什么是迭代器:
对迭代过程的一种封装,通常封装为对象的数据形式,不同的语言中,表现出来的迭代形式也是不一样的
迭代模式:
一种设计模式,用于统一迭代的过程,并且会规范代器的规格
迭代器满足的条件:
1.迭代器有得到数据集合中下一个数据的能力
2.判断是否有后续数据的能力
//写法规范
const obj = {
next(){
return {
value : xxx //数据
done : boolean //判断是否有后续数据,如果有则是false,没有则是ture,默认为false。
}
}
}
例子:
const arr = [1,5,6,8,23,7,8];
const iterator = {
//用于迭代数组的对象,iterator为迭代器的名称
i : 0,
next(){
let result = {
value : arr[this.i],
done : this.i >= arr.length
}
this.i++;
return result;
}
}
// 让迭代器自己取出数据
let data = iterator.next();
while(!data.done){
console.log(data.value)
data = iterator.next()
}
console.log("迭代完成")
//创建一个迭代器的函数
function createIterator(arr){
let i = 0;
return {
next(){
let result = {
value : arr[i],
done : i >= arr.length
}
i++;
return result;
}
}
}
const iter1 = createIterator(arr1)
const iter2 = createIterator(arr2)
迭代器可以迭代数组与类数组
//数组
const arr = [55,52,44,742,75,1]
// //对象具有属性 Symbol.iterator,则表示对象可以使用迭代
const iterator = arr[Symbol.iterator](); //直接创建迭代对象
for(let i = 0; i < arr.length;i ++){
console.log(iterator.next());
}
//类数组
const divs = document.getElementsByTagName("div");
console.log(divs);
let result = iterator.next();
while(!result.done){
console.log(result.value)
result = iterator.next();
}
//for of 专门遍历可迭代的对象
for(let item of arr){
console.log(item)
}
如果一个对象中没有Symbol.iterator属性,可以直接诶在对象中写入这个属性,也可以完成迭代。
const obj = {
a : 1,
b : 2,
c : 3,
[Symbol.iterator](){
const keys = Object.keys(this);
let i = 0;
return {
next:()=>{
const propName = keys[i];
const propValue = this[propName];
const result = {
value :{
propName,//属性即是属性名
propValue,//属性即是属性名
name : "LAILA"
},
done : i >= keys.length
}
i++;
return result;
}
}
}
}
//扩展运算符可用作可迭代对象,迭代对象中的内容直接添加至数组中
function test(a,b,c){
console.log(a,b,c)
}
test(...obj)
什么是生成器:
生成器就是通过构造函数Generator创建出来的一个对象,这个对象即是迭代器,同时也是一个可迭代的对象。
function *test(){
console.log(123)
yield 1;
console.log(456)
yield 2;
console.log(789)
yield 3;
yield 4;
yield 5;
return 6;//最后返回的对象
}
const generator = test();
generator.next()
使用next方法会返回一个对象,这个对象就是一个迭代器对象,对象中的value值就是yield后面跟的值.
注意点:
- async和*不能同时加在一个函数上,因为同时起函数修饰符的作用
- 生成器中的关键字yield 只能在函数内部使用,表示产生一个迭代数据
- 每一次调用生成器的next方法,会将生成器函数运行带yield关键字位置
- 生成器的返回值,出现在最后一次的done为ture的value中
- 调用生成器的next方法时,可以传递参数,这个参数是yield表达式的返回值。
- 第一次调用函数时,传递的参数是没有任何含义的。