[js高手之路] es6系列教程 - 迭代器与生成器详解

什么是迭代器?
迭代器是一种特殊对象,这种对象具备如下特色:
1,全部对象都有一个next方法
2,每次调用next方法,都会返回一个对象,该对象包含两个属性,一个是value, 表示下一个将要返回的值。另外一个是done,他是一个布尔值,用来表示该迭代器是否还有数据能够返回.
3,迭代器还会保存一个内部指针指向当前集合中的值
设计模式中有个迭代模式,跟迭代器是差很少的,我以前有写过2篇文章关于迭代模式:
[js高手之路] 设计模式系列课程 - 迭代器(1)
[js高手之路] 设计模式系列课程 - DOM迭代器(2)
 
用es5的方式,封装一个迭代器:es6

1 function createIterator( arr ){
 2     var i = 0;
 3     return {
 4         next : function(){
 5             var done = ( i >= arr.length );
 6             var value = !done ? arr[i++] : undefined;
 7             return {
 8                 done : done,
 9                 value : value
10             }
11         }
12     };
13 }
14 
15 var iterator = createIterator( [ 10, 20, 30 ] );
16 console.log( iterator.next() ); // { done : false, value : 10 }
17 console.log( iterator.next() ); // { done : false, value : 20 }
18 console.log( iterator.next() ); // { done : false, value : 30 }
19 console.log( iterator.next() ); // { done : true, value : undefined }

而后你再看看是否符合咱们上面说的迭代器对象的特色.
有了迭代器的基础以后,咱们就来看看,什么是生成器?
生成器是一种返回迭代器的函数,经过function关键字后的星号( * )来表示,函数中会用到新的关键字yield.  星号能够紧跟function后面 也能够在function后面加个空格.设计模式

1 function *createIterator(){
 2     yield 10;
 3     yield 20;
 4     yield 30;
 5 }
 6 
 7 var iterator = createIterator();
 8 console.log( iterator.next() ); // { done : false, value : 10 }
 9 console.log( iterator.next() ); // { done : false, value : 20 }
10 console.log( iterator.next() ); // { done : false, value : 30 }
11 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关键字返回数组的当前值数组

1 function *createIterator( arr ){
 2     for( var i = 0, len = arr.length; i < len; i++ ) {
 3         yield arr[i];
 4     }
 5 }
 6 var iterator = createIterator( [ 10, 20, 30 ] );
 7 console.log( iterator.next() ); // { done : false, value : 10 }
 8 console.log( iterator.next() ); // { done : false, value : 20 }
 9 console.log( iterator.next() ); // { done : false, value : 30 }
10 console.log( iterator.next() ); // { done : true, value : undefined }

使用yield关键字,须要注意的地方:
yield关键字只能在生成器内部使用,在生成器内部的函数使用也会报错.函数

1 function show(){
2     yield 10;
3 }
4 show();

这种使用方式会报错,下面这种使用,也会报错es5

1 function *createIterator( arr ){
2     for( var i = 0, len = arr.length; i < len; i++ ) {
3         return function(){
4             yield arr[i];
5         }
6     }
7 }

生成器支持函数表达式的写法,可是不支持箭头函数设计

1 var createIterator = function *( arr ){
 2     for( var i = 0, len = arr.length; i < len; i++ ) {
 3         yield arr[i];
 4     }
 5 }
 6 var iterator = createIterator( [ 10, 20, 30 ] );
 7 console.log( iterator.next() ); // { done : false, value : 10 }
 8 console.log( iterator.next() ); // { done : false, value : 20 }
 9 console.log( iterator.next() ); // { done : false, value : 30 }
10 console.log( iterator.next() ); // { done : true, value : undefined }
1 var createIterator = *( arr )=>{
2     for( var i = 0, len = arr.length; i < len; i++ ) {
3         yield arr[i];
4     }
5 }
1 var *createIterator = ( arr )=>{
2     for( var i = 0, len = arr.length; i < len; i++ ) {
3         yield arr[i];
4     }
5 }

上面这2种箭头写法是不支持的.
生成器能够添加在对象中指针

1 var obj = {
 2     createIterator : function *( arr ){
 3         for( var i = 0, len = arr.length; i < len; i++ ) {
 4             yield arr[i];
 5         }
 6     }
 7 };
 8 var iterator = obj.createIterator( [ 10, 20, 30 ] );
 9 console.log( iterator.next() ); // { done : false, value : 10 }
10 console.log( iterator.next() ); // { done : false, value : 20 }
11 console.log( iterator.next() ); // { done : false, value : 30 }
12 console.log( iterator.next() ); // { done : true, value : undefined }

也能够用对象的简写方式:code

1 var obj = {
 2     *createIterator( arr ){
 3         for( var i = 0, len = arr.length; i < len; i++ ) {
 4             yield arr[i];
 5         }
 6     }
 7 };
 8 var iterator = obj.createIterator( [ 10, 20, 30 ] );
 9 console.log( iterator.next() ); // { done : false, value : 10 }
10 console.log( iterator.next() ); // { done : false, value : 20 }
11 console.log( iterator.next() ); // { done : false, value : 30 }
12 console.log( iterator.next() ); // { done : true, value : undefined }

转载于猿2048:➸[《[js高手之路] es6系列教程 - 迭代器与生成器详解》][1]对象

相关文章
相关标签/搜索