迭代器 iterator
运用场景:React框架,fetch
1. 什么是迭代?
从一个数据集合中按照一定的顺序,不断取出数据的过程
2. 迭代和遍历的区别?
迭代强调依次取出,不能确定取出的数据有多少,也不能保证数据取完
遍历保证知道了数据的长度,循环不断地全部取出,针对于数据量过大的时候使用遍历会花费很多时间
const arr=[1,2,3,4,5];
//遍历
for(let i=0;i<arr.length;i++){
console.log(arr[i])
}
//选择器 (封装)
function create(arr){
let i=0;
return {
next(){
let result={
value:arr[i],
done:i>=arr.length
}
}
i++;
return result;
}
}
const a=create(arr);
console.log(a.next())
3. 迭代器
对迭代过程的封装,通常表现为对象的数据形式(也有数组的形式),不同的语言中,表现出来的形式是不一样
4. 迭代器满足的条件
1.有得到下一个数据的能力
2.判断是否有后续数据的能力
js中的迭代器:
js规定,如果一个对象有next方法,并且返回一个对象,就认为该对象为迭代器
const obj = {
next(){
return {
value : xxx,// 写一个数据
done : xxx//判断是否有后续数据的能力 一般为boolean
}
}
}
ES6之后数组对象Array就已经有迭代器的方法,可以直接使用
在ES6后,如果对象原型上具有知名符号属性Symbol.iterator方法,则表示该对象可迭代
注意:扩展运算符(...)的展开功能只能在可迭代对象上使用
// 斐波那契数列迭代器
function createFeiboIterator(){
let prev1 = 1;
let prev2 = 1;
let n = 1;//当前第几位
return {
next(){
let value;
if(n <= 2){
value = 1
}else{
value = prev1 + prev2;
}
const result = {
value,
done : false
}
prev1 = prev2;
prev2 = result.value;
n++;
return result;
}
}
}
const iterator = createFeiboIterator()
console.log(iterator.next())
生成器 generator
1.什么是生成器?
生成器就是通过构造函数Genterator创建出来的对象,生成器就是一个迭代器,同时又是一个可迭代对象
2.如何创建?
只需要把函数变成Generator函数
加修饰符*
3.生成器的内部执行
4.生成器的作用:控制函数内部代码的执行
function *test(){
console.log("123");
yield "a";
console.log("123")
console.log("123");
yield "b";
console.log("123")
console.log("123")
}
// 函数执行完会返回一个对象就是生成器也是一个迭代器,包括next方法和Symbol
const generator = test()
console.log(generator)
// 注意:async和* 不能同时加,因为async和生成器都是用来修饰函数的
// 生成器中的关键 yield 只能在函数的内部使用,表示一个可迭代数据
生成器注意的点
1.生成器有返回值,出现在最后一次done为true的value值
2.调用生成的next方法是,可以传递参数,传递的参数会交给yield表达式上的返回值
3.第一调用next函数的时候,传递的参数是没有任何含义的
function *test(){
let info = yield 1;
console.log(info)
info = yield 2;
console.log(info)
info = yield 3;
}
let ger = test();
ger.next("a");
ger.next("b");
ger.next("c");
创建一个斐波那契数列的生成器
function* createFeibo(){
let prev1 = 1;
let prev2 = 1;
let n = 1;
while(true){
if(n <= 2){
yield 1;
}else{
const newValue = prev1 + prev2;
yield newValue;
prev1 = prev2;
prev2 = newValue;
}
n++;
}
}
let gener = createFeibo()
gener.next()//{value : 1,done:false}
API
1.return
function *test(){
yield 1;
yield 2;
yield 3;
return 4;
}
const generator = test()
2.throw 可以在生成器中产生一个错误,抛到对应的行
3.在生成器中调用别的生成器
// 在生成器中调用别的生成器
function *fun1(){
yield "a";
yield "b"
}
function *fun2(){
yield 1;
yield 2;
yield 3;
yield *fun1();
}
let ger = fun2()