• 《ECMAScript6入门》笔记——Generator函数


    今天在看《ECMAScript6入门》的第17章——Generator函数的语法。理解起来还是有点费劲,几段代码看了很多遍。总算有点点理解了。

    示例代码如下:(摘自阮一峰《ECMAScript 6 入门》)

    function* foo(x) {
      var y = 2 * (yield (x + 1));
      var z = yield (y / 3);
      return (x + y + z);
    }
    
    var a = foo(5);
    a.next() // Object{value:6, done:false}
    a.next() // Object{value:NaN, done:false}
    a.next() // Object{value:NaN, done:true}
    
    var b = foo(5);
    b.next() // { value:6, done:false }
    b.next(12) // { value:8, done:false }
    b.next(13) // { value:42, done:true }

    看到这段代码的时候有点懵逼~

    首先回顾一下generator知识点:

    1. Generator函数的特征之一:function关键字与函数名之间有一个星号*
    2. Generator函数体内部使用yield表达式——产出
    3. 每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止
    4. yield表达式与return语句的区别:
      • 每次遇到yield,函数暂停执行,下一次再从该位置继续向后执行,而return语句不具备位置记忆的功能。
      • 一个函数里面,只能执行一次return语句,可以执行多次yield表达式。
    5. Generator函数可以返回一系列的值,因为可以有任意多个yield
    6. yield表达式只能用在generator函数里面,用在普通函数中会报错。
    7. yield表达式本身没有返回值,或者说总是返回undefined。
    8. next方法可以带一个参数,该参数会被当做上一个yield表达式的返回值。
    9. done属性:表示是否遍历结束。

    现在再来仔细看一遍上面那段代码:

    首先,定义一个generator函数

    // 定义一个generator函数
    function* foo(x) {
      var y = 2 * (yield (x + 1)); // 第一次调用next方法时,返回第一个yield表达式的值; done:false
      var z = yield (y / 3); // 第二次调用next方法时,返回第二个yield表达式的值; done:false
      return (x + y + z); // 第三次调用next方法时,返回return语句的值;done:true
    }
    // 如果还有第四次调用next方法,返回value:undefined,done:true

    不向next方法提供参数时:

    var a = foo(5); // 调用generator函数foo,生成一个遍历器对象a;此时x = 5
    a.next() // Object{value:6, done:false} 第一次调用next(),启动遍历器对象;此时x=5;返回foo中第一个yield表达式的值,x + 1(即5+1)等于6
    a.next() // Object{value:NaN, done:false} 第二次调用next();此时x=5;由于next缺少参数,导致上一个(即第一个)yield表达式的值为undefined;y = 2 * undefined,即y等于NaN;z = NaN/3,即z等于NaN,因此第二个yield也是返回NaN
    a.next() // Object{value:NaN, done:true} 第三次调用next();此时x=5;由于next缺少参数,导致上一个(即第二个)yield表达式的值为undefined,也就是z等于undefined;因此return返回值是 5 + NaN + undefined,即NaN

    向next方法提供参数时:

    var b = foo(5); // 调用generator函数foo,生成一个遍历器对象b; 此时x=5
    b.next() // { value:6, done:false } 第一个调用next,不用传值,启动遍历器对象;此时x=5;返回值是第一个yield表达式 x+1等于6
    b.next(12) // { value:8, done:false } 第二次调用next,将上一次yield表达式的值设为12,因此y等于2*12,即24;第二个yield返回24/3,即8,同时z=8;
    b.next(13) // { value:42, done:true } 第三次调用next,将上一次yield表达式的值设为13,因此z=13;此时x=5,y=24,所以return语句的值是42

    参考:阮一峰《ECMAScript 6 入门》第17章Generator 函数的语法

  • 相关阅读:
    全站仪定向距离差 方向不差 这样敢放线吗
    关于老王
    cad巧用插件自定义填充图形
    老王教你永不会错的测量坐标方位角计算方法
    jqgrid 点击列头的超链接或按钮时,不触发列排序事件
    jqgrid 将列头设置为超链接或按钮
    jqgrid 设置隔行换色
    jqgrid 设置行编辑为本地端编辑状态
    jqgrid 让隐藏的列在编辑状态时出现且可编辑
    jqgrid 设置编辑行中的某列为下拉选择项
  • 原文地址:https://www.cnblogs.com/cathy1024/p/10421455.html
Copyright © 2020-2023  润新知