[js高手之路] es6系列教程 - 迭代器与生成器详解
2017-09-24 15:31
836 查看
什么是迭代器?
迭代器是一种特殊对象,这种对象具有以下特点:
1,所有对象都有一个next方法
2,每次调用next方法,都会返回一个对象,该对象包含两个属性,一个是value, 表示下一个将要返回的值。另一个是done,他是一个布尔值,用来表示该迭代器是否还有数据可以返回.
3,迭代器还会保存一个内部指针指向当前集合中的值
设计模式中有个迭代模式,跟迭代器是差不多的,我之前有写过2篇文章关于迭代模式:
[js高手之路] 设计模式系列课程 - 迭代器(1)
[js高手之路] 设计模式系列课程 - DOM迭代器(2)
用es5的方式,封装一个迭代器:
然后你再看看是否符合我们上面说的迭代器对象的特点.
有了迭代器的基础之后,我们就来看看,什么是生成器?
生成器是一种返回迭代器的函数,通过function关键字后的星号( * )来表示,函数中会用到新的关键字yield. 星号可以紧跟function后面 也可以在function后面加个空格.
通过上面这段程序,你应该看出来了,结果跟我们之前用es5实现的迭代器是差不多的。但是你在这个生成器函数中压根就没有看见next方法,done和value属性。因为生成器函数内部实现了迭代器。重点要关注下这个yield关键字,它有什么特点?
1,每当执行完一条yield语句,函数就会自动停止执行, 执行完yield 10之后,函数就会自动停止。
2,下一次调用next方法,就会执行yield 20,函数又会自动停止,
3,下一次调用next方法,就会执行yield 30,函数自动停止
4,下一次在调用,没有可以迭代的元素,value返回undefined
用yield关键字返回数组的当前值
使用yield关键字,需要注意的地方:
yield关键字只能在生成器内部使用,在生成器内部的函数使用也会报错.
这种使用方式会报错,下面这种使用,也会报错
生成器支持函数表达式的写法,但是不支持箭头函数
上面这2种箭头写法是不支持的.
生成器可以添加在对象中
也可以用对象的简写方式:
迭代器是一种特殊对象,这种对象具有以下特点:
1,所有对象都有一个next方法
2,每次调用next方法,都会返回一个对象,该对象包含两个属性,一个是value, 表示下一个将要返回的值。另一个是done,他是一个布尔值,用来表示该迭代器是否还有数据可以返回.
3,迭代器还会保存一个内部指针指向当前集合中的值
设计模式中有个迭代模式,跟迭代器是差不多的,我之前有写过2篇文章关于迭代模式:
[js高手之路] 设计模式系列课程 - 迭代器(1)
[js高手之路] 设计模式系列课程 - DOM迭代器(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系列教程 - 迭代器,生成器,for...of,entries,values,keys等详解
- [js高手之路] es6系列教程 - 对象功能扩展详解
- [js高手之路] es6系列教程 - 对象功能扩展详解
- [js高手之路] es6系列教程 - 解构详解
- [js高手之路] es6系列教程 - Set详解与抽奖程序应用实战
- [js高手之路] es6系列教程 - 解构详解
- [js高手之路] es6系列教程 - Map详解以及常用api
- [js高手之路] es6系列教程 - 函数的默认参数详解
- [js高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race)
- [js高手之路] es6系列教程 - 箭头函数详解
- [js高手之路] es6系列教程 - 函数的默认参数详解
- [js高手之路] es6系列教程 - var, let, const详解
- [js高手之路] es6系列教程 - 箭头函数详解
- [js高手之路] es6系列教程 - var, let, const详解
- [js高手之路] es6系列教程 - 新的类语法实战选项卡
- [js高手之路] es6系列教程 - 不定参数与展开运算符(...)
- [js高手之路] es6系列教程
- [js高手之路] html5 canvas系列教程 - 状态详解(save与restore)
- [js高手之路] es6系列教程 - new.target属性与es5改造es6的类语法
- [js高手之路] es6系列教程 - var, let, const详解