• [js高手之路] es6系列教程


    什么是迭代器?

    迭代器是一种特殊对象,这种对象具有以下特点:

    1,所有对象都有一个next方法

    2,每次调用next方法,都会返回一个对象,该对象包含两个属性,一个是value, 表示下一个将要返回的值。另一个是done,他是一个布尔值,用来表示该迭代器是否还有数据可以返回.

    3,迭代器还会保存一个内部指针指向当前集合中的值

    设计模式中有个迭代模式,跟迭代器是差不多的,我之前有写过2篇文章关于迭代模式:

    [js高手之路] 设计模式系列课程 - 迭代器(1)

    [js高手之路] 设计模式系列课程 - DOM迭代器(2)

    用es5的方式,封装一个迭代器:

     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();

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

    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 }

    也可以用对象的简写方式:

     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 }
  • 相关阅读:
    元素的属性
    表单
    Array数组类
    string类
    js数据类型以及原型分析
    this
    有关兼容性的解决
    单位
    滚动条 和 背景位置及绝对定位
    圣杯布局 和 双飞翼布局
  • 原文地址:https://www.cnblogs.com/ghostwu/p/7587327.html
Copyright © 2020-2023  润新知