迭代器
什么是迭代器
迭代是访问集合元素的一种方式。迭代和遍历非常相似,但是还是有区别的:
1. 迭代强调的依次取出,不能确定可以取出的值有多少,也不能保证把数据全部取完
2. 遍历必须保证数据的长度,循环不断的全部取出,针对于数据量过大的情况下使用遍历需要时间过长
迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一 个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
通俗的说,只需要满足以下条件就可以成为迭代器:
1. 取出下一个数据的能力
2. 判断是否有下一个数据
不同的语言中,表现出来的迭代形式不一样。在js中如果规定一个对象有next方法,并且返回一个对象,就认为这个对象是迭代器。
下面根据上面的描述来实现一个简单的迭代器:
const obj = {
next(){ //obj对象中有next()方法
return { // 返回的是一个对象
value : ***, //数据
done : ***, //判断是否有后续数据,一般为boolean值
}
}
}
这就是一个简单的迭代器。用迭代器来实现斐波拉契数列:
function createFeibo(){
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
}
prev2 = prev1;
prev1 = result.value;
n++;
return result
}
}
}
const iter = createFeibo()
在浏览器调用next方法就能拿到数据。
生成器
什么是生成器?
生成器就是通过构造函数genertaor创造出来的对象,生成器既是一个迭代器,同时也是一个可迭代对象。通过上面描述,可能认为是这样创建:
const obj=new Generator()
但是这种创建是错误的,应该这样创建:
function* test(){ //表示当前函数变成generator函数
}
在函数名之前加上*就表示该函数是生成器函数。
生成器中的关键字yield
只能在函数内部使用,表示产生一个迭代数据,每一次调用生成器中的next方法,会将生成器函数运行到下一个yield关键字的位置。
也可以这样理解:当函数运行到这一行的时候,程序会从这里暂停,yield相当于return会返回,当下次迭代时候,则会从yield的下一行代码开始执行。下面用生成器来实现斐波拉契数列:
function *creatrFeribo(){
let pro1 = 1;
let pro2 = 1;
let n = 1;
while(true){
if(n <= 2){
yield 1
}else{
const newValue = pro1 + pro2;
yield newValue;
pro2 = pro1;
pro1 = newValue;
}
n++;
}
}
const iter = creatrFeribo()
注意点:
1.生成器有返回值,出现在最后一次的done为true的value
2.调用生成器中的next方法时,可以传递参数,传递的参数可以交给yield表达式的返回值
3.第一次去调用next时,传递的参数是没有任何含义的
生成器的API
.return()
表示提前结束生成器函数,这个迭代过程也提前结束。
function *test(){
yield 1;
yield 2;
yield 3;
return 4;
}
const generator = test()
使用之后,直接结束了生成器,再次调用next方法值就为undefined,done为true。
.throw ()
可以在生成器产生一个错误,抛出到对应的行中去.