《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知识点:
- Generator函数的特征之一:function关键字与函数名之间有一个星号*
- Generator函数体内部使用yield表达式——产出
- 每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止
- yield表达式与return语句的区别:
- 每次遇到yield,函数暂停执行,下一次再从该位置继续向后执行,而return语句不具备位置记忆的功能。
- 一个函数里面,只能执行一次return语句,可以执行多次yield表达式。
- Generator函数可以返回一系列的值,因为可以有任意多个yield
- yield表达式只能用在generator函数里面,用在普通函数中会报错。
- yield表达式本身没有返回值,或者说总是返回undefined。
- next方法可以带一个参数,该参数会被当做上一个yield表达式的返回值。
- 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函数的更多相关文章
- ES6入门之Generator函数
Generator Generator函数是ES6提供的一种异步编程解决方案,Generator函数是一个状态机,封装了多个内部状态. 执行Generator函数会返回一个遍历器对象,也就是说,Gen ...
- js-ES6学习笔记-Generator函数的异步应用
1.ES6 诞生以前,异步编程的方法,大概有下面四种. 回调函数 事件监听 发布/订阅 Promise 对象 Generator 函数将 JavaScript 异步编程带入了一个全新的阶段. 2.所谓 ...
- js-ES6学习笔记-Generator函数的应用
1.异步操作的同步化表达 Generator函数的暂停执行的效果,意味着可以把异步操作写在yield语句里面,等到调用next方法时再往后执行.这实际上等同于不需要写回调函数了,因为异步操作的后续操作 ...
- js-ES6学习笔记-Generator函数
1.Generator 函数是 ES6 提供的一种异步编程解决方案.形式上,Generator 函数是一个普通函数,但是有两个特征.一是,function关键字与函数名之间有一个星号:二是,函数体内部 ...
- MATLAB菜鸟入门笔记【函数章】
一.用捷径表达式赋值 1.first:incr:last first代表数组的每一个值,incr代表步增量,last代表这个数组的最后一个值. Ep:>>x=1:2:10 ...
- System Generator入门笔记
System Generator入门笔记 [CPLD/FPGA] 发布时间:2010-04-08 23:02:09 System Generator是Xilinx公司进行数字信号处理开发的一种设计 ...
- ECMAScript 6 入门 ----Generator 函数
本文转自:阮一峰老师的ECMAScript 6 入门,有时间可以看下评论! Generator 函数 简介 基本概念 Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不 ...
- Generator 函数学习笔记
// 使用 function* 定义一个 generator 函数 function* helloWorldGenerator() { yield 'hello'; // yield 关键字作为暂停的 ...
- 前端笔记之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 ...
随机推荐
- PopupWindow的一些属性
void setOutsideTouchable(boolean touchable) Controls whether the pop-up will be informed ...
- Typedef和#define之间的区别
Typedef和define都可以用来给对象取一个别名,但是两者却有着很大不同. 1. 首先,二者执行时间不同 关键字typedef在编译阶段有效,由于是在编译阶段,因此typedef有类型检查的功能 ...
- sql创建外键
建立外键关系:先建主表再见从表:主表:create table zhu(code int parimary key,name varchar(20)) ;从表:create table cong(co ...
- java(异常体系及权限修饰符)
java异常体系 异常的体系: 异常体系: --------| Throwable 所有错误或者异常的父类 --------------| Error(错误) --------------| Exce ...
- JavaScript--数据结构算法之链表
数组的缺点:数组的长度固定,增删时比较困难要移动元素,而且数据填满再添加元素比较复杂.js:数组有split(),可以任意的分割.不存在上述问题.主要问题是:js数组都被实现成了对象,和其他语言的数组 ...
- pgrep---以名称为依据从运行进程队列中查找进程
pgrep命令以名称为依据从运行进程队列中查找进程,并显示查找到的进程id.每一个进程ID以一个十进制数表示,通过一个分割字符串和下一个ID分开,默认的分割字符串是一个新行.对于每个属性选项,用户可以 ...
- mount---挂载文件系统
挂载概念 Linux中的根目录以外的文件要想被访问,需要将其“关联”到根目录下的某个目录来实现,这种关联操作就是“挂载”,这个目录就是“挂载点”,解除次关联关系的过程称之为“卸载”. 注意:“挂载点” ...
- 【Codeforces Round #426 (Div. 2) B】The Festive Evening
[Link]:http://codeforces.com/contest/834/problem/B [Description] [Solution] 模拟水题; 注意一个字母单个出现的时候,结束和开 ...
- C# wpf程序获取当前程序版本
C# wpf程序获取当前程序版本 /// <summary> /// 获取当前系统的版本 /// </summary> /// ...
- js30--代理模式
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...