今天在看《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. python-安装xlrd xlwt 插件

    最近需要对比两个表格的内容,然后修改其中的某列内容.因为工作量太大,所以想通过python来实现.上网查了相关的操作,其中牵扯到两个功能模块,xlrd xlwt.这两个功能模块分别是对excel进行读 ...

  2. jquery的ajax总结

    jquery的ajax总结 一.总结 一句话总结:ajax函数中层级关系如下: 最底层的封装方式: $.ajax(); 第二层: .load(),$.get(), $.post() 最高层: $.ge ...

  3. 最大子矩阵和 51Nod 1051 模板题

    一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值. 例如:3*3的矩阵:   -1 3 -1 2 -1 3 -3 1 2   和最大的子矩阵是:   3 - ...

  4. ifconfig---配置和显示Linux内核中网络接口

    ifconfig命令被用于配置和显示Linux内核中网络接口的网络参数.用ifconfig命令配置的网卡信息,在网卡重启后机器重启后,配置就不存在.要想将上述的配置信息永远的存的电脑里,那就要修改网卡 ...

  5. c# 用代码来设置程序的PrivatePath

    原文:c# 用代码来设置程序的PrivatePath 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sweety820/article/detail ...

  6. 图片上传4-bug修复

    bug1:显示图片的时候,需要判断url是否为空 <#if photo.url != null> <img id="${photo.id}-img" src=&q ...

  7. Hibernate5配置与使用具体解释

    转载请注明出处:http://blog.csdn.net/tyhj_sf/article/details/51851163 引言 Hibernate是一个轻量级的持久层开源框架,它是连接java应用程 ...

  8. hdu 1863 畅通project kruskal || prim

    简单最小生成树,畅通project.这三道题目都是练习最小生成树的. 注意一下推断是否有通路时,kruskal能够推断每一个点的祖先是否同样.prim能够推断每一个点是否都加进集合里面了,也就是说是否 ...

  9. Appium IOS 自己主动化測试初探

    手机平台的自己主动化測试工具非常多,之前研究过了安卓和苹果的原生自己主动化測试框架.经一些同事介绍,貌似Appium是个不错的工具. 想记录一下研究的结果,也算是篇干货的文章 在网上也看了一些视频.个 ...

  10. Flume的可靠性

    Flume的可靠性 当节点出现故障时,日志能够被传送到其他节点上而不会丢失. Flume提供了三种级别的可靠性保障,从强到弱依次分别为:end-to- end(收到数据agent首先将event写到磁 ...