首页 > 语言 > JavaScript > 正文

详谈ES6中的迭代器(Iterator)和生成器(Generator)

2024-05-06 15:13:36
字体:
来源:转载
供稿:网友

前面的话

用循环语句迭代数据时,必须要初始化一个变量来记录每一次迭代在数据集合中的位置,而在许多编程语言中,已经开始通过程序化的方式用迭代器对象返回迭代过程中集合的每一个元素

迭代器的使用可以极大地简化数据操作,于是ES6也向JS中添加了这个迭代器特性。新的数组方法和新的集合类型(如Set集合与Map集合)都依赖迭代器的实现,这个新特性对于高效的数据处理而言是不可或缺的,在语言的其他特性中也都有迭代器的身影:新的for-of循环、展开运算符(...),甚至连异步编程都可以使用迭代器

本文将详细介绍ES6中的迭代器(Iterator)和生成器(Generator)

引入

下面是一段标准的for循环代码,通过变量i来跟踪colors数组的索引,循环每次执行时,如果i小于数组长度len则加1,并执行下一次循环

var colors = ["red", "green", "blue"];for (var i = 0, len = colors.length; i < len; i++) { console.log(colors[i]);}

虽然循环语句语法简单,但如果将多个循环嵌套则需要追踪多个变量,代码复杂度会大大增加,一不小心就错误使用了其他for循环的跟踪变量,从而导致程序出错。迭代器的出现旨在消除这种复杂性并减少循环中的错误

迭代器

迭代器是一种特殊对象,它具有一些专门为迭代过程设计的专有接口,所有的迭代器对象都有一个next()方法,每次调用都返回一个结果对象。结果对象有两个属性:一个是value,表示下一个将要返回的值;另一个是done,它是一个布尔类型的值,当没有更多可返回数据时返回true。迭代器还会保存一个内部指针,用来指向当前集合中值的位置,每调用一次next()方法,都会返回下一个可用的值


如果在最后一个值返回后再调用next()方法,那么返回的对象中属性done的值为true,属性value则包含迭代器最终返回的值,这个返回值不是数据集的一部分,它与函数的返回值类似,是函数调用过程中最后一次给调用者传递信息的方法,如果没有相关数据则返回undefined

下面用ES5的语法创建一个迭代器

function createIterator(items) { var i = 0; return {  next: function() {   var done = (i >= items.length);   var value = !done ? items[i++] : undefined;   return {    done: done,    value: value   };  } };}var iterator = createIterator([1, 2, 3]);console.log(iterator.next()); // "{ value: 1, done: false }"console.log(iterator.next()); // "{ value: 2, done: false }"console.log(iterator.next()); // "{ value: 3, done: false }"console.log(iterator.next()); // "{ value: undefined, done: true }"// 之后的所有调用console.log(iterator.next()); // "{ value: undefined, done: true }"

在上面这段代码中,createIterator()方法返回的对象有一个next()方法,每次调用时,items数组的下一个值会作为value返回。当i为3时,done变为true;此时三元表达式会将value的值设置为undefined。最后两次调用的结果与ES6迭代器的最终返回机制类似,当数据集被用尽后会返回最终的内容

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选