JS中的迭代器和生成器,常常用来处理集合。
前置知识:
JavaScrip已经提供多个迭代集合的方法,从简单的for循环到map()和filter()。
迭代器和生成器将迭代的概念直接带入核心语言,并提供一种机制来自定义for...of循环的行为。
1. 概述
当我们使用循环语句迭代数据时,需初始化一个变量来记录每一次迭代在数据集合中的位置:
let a = ["aaa","bbb","ccc"];
for (let i = 0; i< a.length; i++){
console.log(a);
}
这边的i就是我们用来记录迭代位置的变量,但是在ES6开始,JavaScrip引入了迭代器这个特性,并且新的数组方法和新的集合类型(如Set集合与Map集合)都依赖迭代器的实现,这个新特性对于高效的数据处理而言是不可或缺的,在语言的其他特性中也都有迭代器的身影:新的for-of循环、展开运算符(...),甚至连异步编程都可以使用迭代器。2. 迭代器(简单介绍)
迭代器是一种特殊对象,它具有一些专门为迭代过程设计的专有接口,所有的迭代器对象都有一个next()方法,每次调用都会返回一个结果对象。
这个结果对象,有两个属性:
value: 表示下一个将要返回的值。
done: 一个布尔值,若没有更多可返回的数据时,值为true,否则false。
如果最后一个值返回后,再调用next(),则返回的对象的done值为true,而value值如果没有值的话,返回的为undefined。
ES5实现一个迭代器:
function myIterator(list){
var i = 0;
return {
next: function(){
var done = i >= list.length;
var value = !done ? list[i++] : undefined;
return {
done : done,
value : value
}
}
}
}
var iterator = myIterator([1,2,3]);
iterator.next(); // "{done: false, value: 1}"
iterator.next(); // "{done: false, value: 2}"
iterator.next(); // "{done: false, value: 3}"
iterator.next(); // "{done: true, value: undefined}"
// 以后的调用都一样
iterator.next(); // "{done: true, value: undefined}"
从上面代码可以看出,ES5的实现还是比较麻烦,而ES6新增的生成器,可以使得创建迭代器对象的过程更加简单。3. 生成器(简单介绍)
生成器是一种返回迭代器的函数,通过function关键字后的星号(*)来表示,函数中会用到新的关键字yield。星号可以紧挨着function关键字,也可以在中间添加一个空格。
function *myIterator(){
yield 1;
yield 2;
yield 3;
}
let iterator = myIterator();
iterator.next(); // "{done: false, value: 1}"
iterator.next(); // "{done: false, value: 2}"
iterator.next(); // "{done: false, value: 3}"
iterator.next(); // "{done: true, value: undefined}"
// 以后的调用都一样
iterator.next(); // "{done: true, value: undefined}"
生成器函数最有趣的部分是,每当执行完一条yield语句后函数就会自动停止执行,比如上面代码,当yield 1;执行完后,便不会执行任何语句,而是等到再调用迭代器的next()方法才会执行下一个语句,即yield 2;.
使用yield关键字可以返回任何值和表达式,因为可以通过生成器函数批量给迭代器添加元素:
function *myIterator(list){
for(let i = 0; i< list.length ; i ++){
yield list;
}
}
var iterator = myIterator([1,2,3]);
iterator.next(); // "{done: false, value: 1}"
iterator.next(); // "{done: false, value: 2}"
iterator.next(); // "{done: false, value: 3}"
iterator.next(); // "{done: true, value: undefined}"
// 以后的调用都一样
iterator.next(); // "{done: true, value: undefined}"
生成器的适用返回很广,可以将它用于所有支持函数使用的地方。
以上就是本文的全部内容,感谢大家支持JScript之家——编程学习者社区!
|
|