ES6新特性三: Generator(生成器)函数详解


Posted in Javascript onApril 21, 2017

本文实例讲述了ES6新特性三: Generator(生成器)函数。分享给大家供大家参考,具体如下:

1. 简介

① 理解:可以把它理解成一个函数的内部状态的遍历器,每调用一次,函数的内部状态发生一次改变。

② 写法:

function* f() {}

③ 作用:就是可以完全控制函数的内部状态的变化,依次遍历这些状态。

④ 运行过程:当调用Generator函数的时候,该函数并不执行,而是返回一个遍历器(可以理解成暂停执行)。通过调用next()开始执行,遇到yield停止执行,返回一个value属性值为当前yield语句的值,done属性为false的对象,循环调用next(),一直执行到return语句(如果没有return语句,就执行到函数结束)。next方法返回的对象的value属性,就是紧跟在return语句后面的表达式的值(如果没有return语句,则value属性的值为undefined),done属性的值true,表示遍历已经结束。

示例:

function* helloWorldGenerator() {
 yield 'hello';
 yield 'world';
 return 'ending';
}
var hw = helloWorldGenerator();//第一次调用该方法不会执行,仅返回一个遍历器。
var a = hw.next();
while(!a.done){ //当执行到return 时,a.done=true,终止循环
 console.log(a.value+','+a.done);
 a = hw.next();
}
console.log(a.value+','+a.done);

结果:

hello,false
world,false
ending,true

2. next() 的参数

① 我们要知道是next()返回一个对象,yield语句本身是没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield语句的返回值

function* f() {
 for(var i=0; true; i++) {
  var reset = yield i;
  console.log(reset); //打印reset,验证yield语句是没有返回值的
  if(reset) { i = -1; }
 }
}
var g = f();
console.log(g.next()) // { value: 0, done: false }
console.log(g.next())// { value: 1, done: false }
console.log(g.next(true)) // { value: 0, done: false }

结果:

{ value: 0, done: false }
undefined
{ value: 1, done: false }
true
{ value: 0, done: false }

通过next方法的参数,就有办法在Generator函数开始运行之后,继续向函数体内部注入值。也就是说,可以在Generator函数运行的不同阶段,从外部向内部注入不同的值,从而调整函数行为。

②由于next方法的参数表示上一个yield语句的返回值,所以第一次使用next方法时,不能带有参数。V8引擎直接忽略第一次使用next方法时的参数,只有从第二次使用next方法开始,参数才是有效的。

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

3. for-of 遍历generator

for...of循环可以自动遍历Generator函数,且此时不再需要调用next方法,

一旦next方法的返回对象的done属性为true,for...of循环就会中止,且不包含该返回对象

function *foo() {
 yield 1;
 yield 2;
 yield 3;
 yield 4;
 yield 5;
 return 6;
}
for (let v of foo()) {
 console.log(v);
}
// 1 2 3 4 5

4. yield* 语句

① 如果yield命令后面跟的是一个遍历器,需要在yield命令后面加上星号,表明它返回的是一个遍历器。这被称为yield*语句。

let a = (function* () {
 yield 'Hello!';
 yield 'Bye!';
}());
let b = (function* () {
 yield 'Greetings!';
 yield* a;
 yield 'Ok, bye.';
}());
for(let value of b) {
 console.log(value);
}

结果:

Greetings!
Hello!
Bye!
Ok, bye.

② yield命令后面如果不加星号,返回的是整个数组,加了星号就表示返回的是数组的遍历器。

function* gen(){
 yield* ["a", "b", "c"];
}
gen().next() // { value:"a", done:false }

遍历嵌套数组:

function* iterTree(tree) {
 if (Array.isArray(tree)) {
 for(let i=0; i < tree.length; i++) {
  yield* iterTree(tree[i]);
 }
 } else {
 yield tree;
 }
}
const tree = [ 'a', ['b', 'c'], ['d', 'e'] ];
for(let x of iterTree(tree)) {
 console.log(x);
}// a b c d e

希望本文所述对大家ECMAScript程序设计有所帮助。

Javascript 相关文章推荐
Mootools 1.2教程 滚动条(Slider)
Sep 15 Javascript
关于JavaScript中var声明变量作用域的推断
Dec 16 Javascript
js中关于new Object时传参的一些细节分析
Mar 13 Javascript
jquery解析xml字符串简单示例
Apr 11 Javascript
JS实现的仿东京商城菜单、仿Win右键菜单及仿淘宝TAB特效合集
Sep 28 Javascript
javascript html5摇一摇功能的实现
Apr 19 Javascript
Bootstrap CSS组件之输入框组
Dec 17 Javascript
基于Node.js实现压缩和解压缩的方法
Feb 13 Javascript
Swiper 4.x 使用方法(移动端网站的内容触摸滑动)
May 17 Javascript
JS实现前端页面的搜索功能
Jun 12 Javascript
Vue动态加载异步组件的方法
Nov 21 Javascript
使用node搭建自动发图文微博机器人的方法
Mar 22 Javascript
Cookies 和 Session的详解及区别
Apr 21 #Javascript
node.js(express)中使用Jcrop进行图片剪切上传功能
Apr 21 #Javascript
原生javascript实现分页效果
Apr 21 #Javascript
微信小程序 跳转方式总结
Apr 20 #Javascript
微信小程序 setData的使用方法详解
Apr 20 #Javascript
ES6新特性二:Iterator(遍历器)和for-of循环详解
Apr 20 #Javascript
微信小程序中form 表单提交和取值实例详解
Apr 20 #Javascript
You might like
世界上第一台立体声收音机
2021/03/01 无线电
十天学会php之第八天
2006/10/09 PHP
shopex中集成的站长统计功能的代码简单分析
2011/08/11 PHP
PHP基础知识回顾
2012/08/16 PHP
php二维数组排序与默认自然排序的方法介绍
2013/04/27 PHP
CI(CodeIgniter)框架介绍
2014/06/09 PHP
JAVASCRIPT HashTable
2007/01/22 Javascript
学习YUI.Ext基础第一天
2007/03/10 Javascript
33种Javascript 表格排序控件收集
2009/12/03 Javascript
五个jQuery图片画廊插件 推荐
2011/05/12 Javascript
iframe窗口高度自适应的又一个巧妙实现思路
2014/04/04 Javascript
JavaScript实现列表分页功能特效
2015/05/15 Javascript
javascript字符串与数组转换汇总
2015/05/26 Javascript
javascript实现checkbox复选框实例代码
2016/01/10 Javascript
JavaScript几种数组去掉重复值的方法推荐
2016/04/12 Javascript
vue项目优化之通过keep-alive数据缓存的方法
2017/12/11 Javascript
vue-cli项目修改文件热重载失效的解决方法
2018/09/19 Javascript
CKEditor 4.4.1 添加代码高亮显示插件功能教程【使用官方推荐Code Snippet插件】
2019/06/14 Javascript
Python的Flask框架与数据库连接的教程
2015/04/20 Python
python实现数独算法实例
2015/06/09 Python
浅谈Django中的数据库模型类-models.py(一对一的关系)
2018/05/30 Python
python中for循环变量作用域及用法详解
2019/11/05 Python
python实现智能语音天气预报
2019/12/02 Python
Macbook安装Python最新版本、GUI开发环境、图像处理、视频处理环境详解
2020/02/17 Python
Python print不能立即打印的解决方式
2020/02/19 Python
CSS3动画和HTML5新特性详解
2020/08/31 HTML / CSS
Vichy薇姿加拿大官网:法国药妆,全球专业敏感肌护肤领先品牌
2018/07/11 全球购物
娇韵诗香港官网:Clarins香港
2020/08/13 全球购物
一年级语文教学反思
2014/02/13 职场文书
安全月活动总结
2014/05/05 职场文书
就职演讲稿范文
2014/05/19 职场文书
2015年班组建设工作总结
2015/05/13 职场文书
2015-2016年小学教导工作总结
2015/07/21 职场文书
如何利用js在两个html窗口间通信
2021/04/27 Javascript
Python如何导出导入所有依赖包详解
2021/06/08 Python
动画《平凡职业成就世界最强》宣布制作OVA
2022/04/01 日漫