今天在看《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 函数的语法

《ECMAScript6入门》笔记——Generator函数的更多相关文章

  1. ES6入门之Generator函数

    Generator Generator函数是ES6提供的一种异步编程解决方案,Generator函数是一个状态机,封装了多个内部状态. 执行Generator函数会返回一个遍历器对象,也就是说,Gen ...

  2. js-ES6学习笔记-Generator函数的异步应用

    1.ES6 诞生以前,异步编程的方法,大概有下面四种. 回调函数 事件监听 发布/订阅 Promise 对象 Generator 函数将 JavaScript 异步编程带入了一个全新的阶段. 2.所谓 ...

  3. js-ES6学习笔记-Generator函数的应用

    1.异步操作的同步化表达 Generator函数的暂停执行的效果,意味着可以把异步操作写在yield语句里面,等到调用next方法时再往后执行.这实际上等同于不需要写回调函数了,因为异步操作的后续操作 ...

  4. js-ES6学习笔记-Generator函数

    1.Generator 函数是 ES6 提供的一种异步编程解决方案.形式上,Generator 函数是一个普通函数,但是有两个特征.一是,function关键字与函数名之间有一个星号:二是,函数体内部 ...

  5. MATLAB菜鸟入门笔记【函数章】

    一.用捷径表达式赋值 1.first:incr:last   first代表数组的每一个值,incr代表步增量,last代表这个数组的最后一个值. Ep:>>x=1:2:10        ...

  6. System Generator入门笔记

    System Generator入门笔记  [CPLD/FPGA] 发布时间:2010-04-08 23:02:09  System Generator是Xilinx公司进行数字信号处理开发的一种设计 ...

  7. ECMAScript 6 入门 ----Generator 函数

    本文转自:阮一峰老师的ECMAScript 6 入门,有时间可以看下评论! Generator 函数 简介 基本概念 Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不 ...

  8. Generator 函数学习笔记

    // 使用 function* 定义一个 generator 函数 function* helloWorldGenerator() { yield 'hello'; // yield 关键字作为暂停的 ...

  9. 前端笔记之ES678&Webpack&Babel(下)AMD|CMD规范&模块&webpack&Promise对象&Generator函数

    一.AMD和CMD规范(了解) 1.1传统的前端开发多个js文件的关系 yuan.js中定义了一个函数 function mianji(r){ return 3.14 * r * r } main.j ...

随机推荐

  1. 视图中使用ROWNUM要注意

    昨天晚上帮一位兄弟优化一个ebs的sql. sql有好几百行. SQL的样子是select .... from 视图 where ....过滤条件 视图的代码贴出来就不给大家看了,比較长.另外设计保密 ...

  2. Android中关于Volley的使用(十)对Request和Reponse的认识

    我们知道,在网络Http通信中.一定会有一个Request.相同的,也一定会有一个Response.而我们在Volley中利用RequestQueue来加入请求之前,一定会先创建一个Request对象 ...

  3. Scott Hanselman的问题-1

    Scott Hanselman的问题 .Net 程序员面试 C# 语言篇 (回答Scott Hanselman的问题)   过去几年都在忙着找项目,赶项目,没有时间好好整理深究自己在工作中学到的东西. ...

  4. Android webview 运行时不调用系统自带浏览器

    WebView mobView = new WebView(this); mobView.loadUrl("http://www.csdn.net"); WebSettings w ...

  5. Codefroces Educational Round 27 845G Shortest Path Problem?

    Shortest Path Problem? You are given an undirected graph with weighted edges. The length of some pat ...

  6. java bigdecimal (java double也时会失真)

    BigDecimal加减乘除运算 2011-11-21 21:22 6470人阅读 评论(0) 收藏 举报 stringdivjavaup工具 java.math.BigDecimal.BigDeci ...

  7. Input/output subsystem having an integrated advanced programmable interrupt controller for use in a personal computer

    A computer system is described having one or more host processors, a host chipset and an input/outpu ...

  8. C++ static 静态成员变量 和 静态成员函数

    静态(static) 成员 变量 1•  静态成员变量的初始化须要在类外完毕. 2•  静态成员不属于详细的某个对象,而属于整个类: 3•  全部对象共享本类中的静态成员: 4•  静态成员最好直接通 ...

  9. (43)JS运动之链式运动框架

    链式运动框架就是一系列的运动分阶段进行,在普通的运动框架上加上一个參数function,这个function表示下一个要运行的动作.详细代码例如以下: <!DOCTYPE HTML> &l ...

  10. CMake设置生成vs工程的动态库输出路径

    作者:朱金灿 来源:http://blog.csdn.net/clever101 在网上搜了很多的资料,发现CMake不能设置一个动态库工程的输出目录和中间目录,难道除了VC之外其它编译器如gcc中没 ...