标题:详解JS前端使用迭代器和生成器原理及示例
什么是迭代器
迭代器是一种设计模式,它提供了一种顺序访问聚合对象元素的方法,而不需要暴露对象的内部表示。迭代器可以分为内部迭代器和外部迭代器。在JavaScript中,数组就是一个内部迭代器。
内部迭代器: 它的迭代规则已经被提前规定,对于每一次迭代,外界没有任何变量参与。这样做的优点是内部迭代器的调用非常简单,外界不用关心迭代器的实现细节,只需要一次初始调用即可。
下面是一个内部迭代器的示例:
function forEach(arr, fn){
for(var i = 0, l = arr.length; i < l; i++){
fn(arr[i], i, arr);
}
}
var arr = [1, 2, 3];
forEach(arr, function(item, index, array){
console.log(item, index, array);
});
什么是生成器
生成器是ES6里面引入的一种迭代器,是一种更加灵活的迭代器,它可以动态产生迭代器的过程。生成器函数使用function *
语法定义。它能够像一般函数一样使用return返回一个值并结束函数,也能够通过yield返回值并暂停函数执行,等待下一次调用时再继续执行。生成器在需要消耗大量时间的操作时,可以极大地提高效率和性能。
下面是一个生成器的示例:
function* gen(){
console.log(1);
yield;
console.log(2);
return 3;
}
const it = gen();
it.next(); // 输出1,执行到第一个yield
it.next(); // 输出2,执行到return,输出3,结束执行
迭代器和生成器的原理
迭代器的实现原理是利用闭包。每调用一次迭代器,都返回一个函数,在每次外部函数调用内部函数时,都会使得闭包中的状态改变,从而实现对下一次迭代的控制。
生成器的实现原理同样利用闭包。定义生成器函数时,会通过yield将生成器函数分割为若干个部分,每次执行next()方法时,都会继续执行生成器函数直至遇到下一个yield语句,返回结果或函数执行结束。生成器函数在执行时会暂停并保存其上下文,这样在需要恢复执行时可以继续执行。每次执行next()方法后,生成器函数都会从保存的上下文中恢复执行。
迭代器和生成器的使用示例
下面是一个使用ES6中生成器来实现斐波那契数列的示例:
function* fibonacci(){
let prev = 1, cur = 1;
while(true){
yield cur;
[prev, cur] = [cur, prev + cur]; //注意这里的解构赋值写法
}
}
let it = fibonacci();
for(let i = 0; i < 10; i++){
console.log(it.next().value);
}
下面是一个使用迭代器来实现数组去重的示例:
function unique(arr){
const set = new Set();
return function* (){
for(const item of arr){
if(!set.has(item)){
set.add(item);
yield item;
}
}
}();
}
const arr = [1,2,2,3,3,4,4,4,5,5];
const it = unique(arr);
for(let item of it){
console.log(item); // 1 2 3 4 5
}
这个示例中,unique()函数返回一个生成器对象,进行去重操作。每次循环时,先判断当前元素是否在Set集合内,如果不在就把它加入集合,然后通过yield来输出这个元素。这个函数每返回一个新值,都会保存当前状态,下一次执行时,从上次暂停的地方继续执行。而使用for...of循环遍历生成器对象,使得整个过程更加简洁明了,易于理解。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解JS前端使用迭代器和生成器原理及示例 - Python技术站