[js高手之路] es6系列教程 - 迭代器与生成器详解
什么是迭代器?
迭代器是一种特殊对象,这种对象具有以下特点:
1,所有对象都有一个next方法
2,每次调用next方法,都会返回一个对象,该对象包含两个属性,一个是value, 表示下一个将要返回的值。另一个是done,他是一个布尔值,用来表示该迭代器是否还有数据可以返回.
3,迭代器还会保存一个内部指针指向当前集合中的值
设计模式中有个迭代模式,跟迭代器是差不多的,我之前有写过2篇文章关于迭代模式:
用es5的方式,封装一个迭代器:
function createIterator( arr ){
var i = 0;
return {
next : function(){
var done = ( i >= arr.length );
var value = !done ? arr[i++] : undefined;
return {
done : done,
value : value
}
}
};
}
var iterator = createIterator( [ 10, 20, 30 ] );
console.log( iterator.next() ); // { done : false, value : 10 }
console.log( iterator.next() ); // { done : false, value : 20 }
console.log( iterator.next() ); // { done : false, value : 30 }
console.log( iterator.next() ); // { done : true, value : undefined }
然后你再看看是否符合我们上面说的迭代器对象的特点.
有了迭代器的基础之后,我们就来看看,什么是生成器?
生成器是一种返回迭代器的函数,通过function关键字后的星号( * )来表示,函数中会用到新的关键字yield. 星号可以紧跟function后面 也可以在function后面加个空格.
function *createIterator(){
yield 10;
yield 20;
yield 30;
}
var iterator = createIterator();
console.log( iterator.next() ); // { done : false, value : 10 }
console.log( iterator.next() ); // { done : false, value : 20 }
console.log( iterator.next() ); // { done : false, value : 30 }
console.log( iterator.next() ); // { done : true, value : undefined }
通过上面这段程序,你应该看出来了,结果跟我们之前用es5实现的迭代器是差不多的。但是你在这个生成器函数中压根就没有看见next方法,done和value属性。因为生成器函数内部实现了迭代器。重点要关注下这个yield关键字,它有什么特点?
1,每当执行完一条yield语句,函数就会自动停止执行, 执行完yield 10之后,函数就会自动停止。
2,下一次调用next方法,就会执行yield 20,函数又会自动停止,
3,下一次调用next方法,就会执行yield 30,函数自动停止
4,下一次在调用,没有可以迭代的元素,value返回undefined
用yield关键字返回数组的当前值
function *createIterator( arr ){
for( var i = 0, len = arr.length; i < len; i++ ) {
yield arr[i];
}
}
var iterator = createIterator( [ 10, 20, 30 ] );
console.log( iterator.next() ); // { done : false, value : 10 }
console.log( iterator.next() ); // { done : false, value : 20 }
console.log( iterator.next() ); // { done : false, value : 30 }
console.log( iterator.next() ); // { done : true, value : undefined }
使用yield关键字,需要注意的地方:
yield关键字只能在生成器内部使用,在生成器内部的函数使用也会报错.
function show(){
yield 10;
}
show();
这种使用方式会报错,下面这种使用,也会报错
function *createIterator( arr ){
for( var i = 0, len = arr.length; i < len; i++ ) {
return function(){
yield arr[i];
}
}
}
生成器支持函数表达式的写法,但是不支持箭头函数
var createIterator = function *( arr ){
for( var i = 0, len = arr.length; i < len; i++ ) {
yield arr[i];
}
}
var iterator = createIterator( [ 10, 20, 30 ] );
console.log( iterator.next() ); // { done : false, value : 10 }
console.log( iterator.next() ); // { done : false, value : 20 }
console.log( iterator.next() ); // { done : false, value : 30 }
console.log( iterator.next() ); // { done : true, value : undefined }
var createIterator = *( arr )=>{
for( var i = 0, len = arr.length; i < len; i++ ) {
yield arr[i];
}
}
var *createIterator = ( arr )=>{
for( var i = 0, len = arr.length; i < len; i++ ) {
yield arr[i];
}
}
上面这2种箭头写法是不支持的.
生成器可以添加在对象中
var obj = {
createIterator : function *( arr ){
for( var i = 0, len = arr.length; i < len; i++ ) {
yield arr[i];
}
}
};
var iterator = obj.createIterator( [ 10, 20, 30 ] );
console.log( iterator.next() ); // { done : false, value : 10 }
console.log( iterator.next() ); // { done : false, value : 20 }
console.log( iterator.next() ); // { done : false, value : 30 }
console.log( iterator.next() ); // { done : true, value : undefined }
也可以用对象的简写方式:
var obj = {
*createIterator( arr ){
for( var i = 0, len = arr.length; i < len; i++ ) {
yield arr[i];
}
}
};
var iterator = obj.createIterator( [ 10, 20, 30 ] );
console.log( iterator.next() ); // { done : false, value : 10 }
console.log( iterator.next() ); // { done : false, value : 20 }
console.log( iterator.next() ); // { done : false, value : 30 }
console.log( iterator.next() ); // { done : true, value : undefined }
[js高手之路] es6系列教程 - 迭代器与生成器详解的更多相关文章
- [js高手之路] es6系列教程 - 对象功能扩展详解
第一:字面量对象的方法,支持缩写形式 //es6之前,这么写 var User = { name : 'ghostwu', showName : function(){ return this.nam ...
- [js高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race)
关于promise我在之前的文章已经应用过好几次,如[js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist,本文就来讲解下pro ...
- [js高手之路] es6系列教程 - var, let, const详解
function show( flag ){ console.log( a ); if( flag ){ var a = 'ghostwu'; return a; } else { console.l ...
- [js高手之路] es6系列教程 - 迭代器,生成器,for...of,entries,values,keys等详解
接着上文[js高手之路] es6系列教程 - 迭代器与生成器详解继续. 在es6中引入了一个新的循环结构for ....of, 主要是用来循环可迭代的对象,那么什么是可迭代的对象呢? 可迭代的对象一般 ...
- [js高手之路] es6系列教程 - 函数的默认参数详解
在ES6之前,我们一般用短路表达式处理默认参数 function show( a, b ){ var a = a || 10; var b = b || 20; console.log( a, b ) ...
- [js高手之路] es6系列教程 - 箭头函数详解
箭头函数是es6新增的非常有意思的特性,初次写起来,可能会觉得别扭,习惯之后,会发现很精简. 什么是箭头函数? 箭头函数是一种使用箭头( => )定义函数的新语法, 主要有以下特性: 不能通过n ...
- [js高手之路] es6系列教程 - 不定参数与展开运算符(...)
三个点(...)在es6中,有两个含义: 用在形参中, 表示传递给他的参数集合, 类似于arguments, 叫不定参数. 语法格式: 在形参面前加三个点( ... ) 用在数组前面,可以把数组的值 ...
- [js高手之路]es6系列教程 - 解构详解
解构通俗点说,就是通过一种特定格式,快捷的读取对象/数组中的数据的方法, es6之前,我们通过对象名称[键] 读取数据 var User = { 'name' : 'ghostwu', 'age' : ...
- [js高手之路] es6系列教程 - Set详解与抽奖程序应用实战
我们还是从一些现有的需求和问题出发,为什么会有set,他的存在是为了解决什么问题? 我们看一个这样的例子,为一个对象添加键值对 var obj = Object.create( null ); obj ...
随机推荐
- JSON WEB TOKEN - 告别session和cookie - java demo
JWT简介 JWT认证流程: 用户登录成功,生成token,返回一个对象(包含token,用户名) 每次请求都带上这个对象(通过js存储在电脑) jwt过滤器会校验token解密之后的name是否和用 ...
- Linux中的定时任务at、crontab
at at命令可以用来在某一时段执行一次任务,只会执行一次,不会重复执行. at命令是由atd服务来控制的,使用之前先查看atd服务是否正常: $ /etc/init.d/atd status * a ...
- jQuery ajax error函数(交互错误信息的获取)
一般error函数返回的参数有三个: function(jqXHR jqXHR, String textStatus, String errorThrown).常见调用代码如下: $.ajax({ u ...
- open文件操作之mode模式剖析
Python可以使用open函数来实现文件的打开,关闭,读写操作: Python3中的open函数定义为: open(file, mode='r', buffering=None, encoding= ...
- spring基于注解进行注入(个人记录)
spring的Bean基于注解进行配置,再结合自动装配属性,也就DI,其实说白了就相当于初始化的时候给对象赋初值. 配置文件的过程有些麻烦,记录一下. 基于注解进行配置: 1.在application ...
- 【Vue】Vue中的父子组件通讯以及使用sync同步父子组件数据
前言: 之前写过一篇文章<在不同场景下Vue组件间的数据交流>,但现在来看,其中关于“父子组件通信”的介绍仍有诸多缺漏或者不当之处, 正好这几天学习了关于用sync修饰符做父子组件数据双向 ...
- 如何修改int的打印内容——史上最难的JAVA面试题
序 今天看到了一个比较特别的面试题,考察的是如何改变int的System.out.print的结果.题目如下: 下面的一句话"这是初级java实习生面试题"非常挑衅的激起了大家做题 ...
- Centos 6修复/boot目录及fstab等系统文件
author:JevonWei 版权声明:原创作品 错误界面 系统修复过程中,若需要修复fatab挂载文件,磁盘分区为lvm逻辑卷格式,则默认在修复模式下处于不可活动状态,需使用vgchage -ay ...
- el-input监听不了回车事件
vue使用element-ui的el-input监听不了回车事件,原因应该是element-ui自身封装了一层input标签之后,把原来的事件隐藏了,所以如下代码运行是无响应的: <el-inp ...
- IBM与麻省理工学院联合建立AI实验室 承诺投资2.4亿美元
IBM和麻省理工学院将通过今天宣布的一个新的联合实验室共同努力,对人工智能进行广泛的研究.麻省理工学院IBM沃森AI实验室将重点关注四个研究支柱:开发AI算法,使用物理学来创建AI计算的新硬 ...