本文实例讲述了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

ES6新特性三: Generator(生成器)函数详解的更多相关文章

  1. java8新特性(四)_Stream详解

    之前写过一篇用stream处理map的文章,但是对stream没有一个整体的认识,这次结合并发编程网和ibm中介绍stream的文章进行一个总结,我会着重写对list的处理,毕竟实际工作中大家每天进行 ...

  2. 三、python函数详解

    函数的定义: 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 定义规则: 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号(). 任何传入参数和自变量必须放在圆括号中间 ...

  3. ASP.NET MVC5 新特性:Attribute路由使用详解 (转载)

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  4. Java新特性之Nashorn的实例详解

    Nashorn是什么 Nashorn,发音“nass-horn”,是德国二战时一个坦克的命名,同时也是java8新一代的javascript引擎--替代老旧,缓慢的Rhino,符合 ECMAScrip ...

  5. ASP.NET MVC5 新特性:Attribute路由使用详解

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  6. 前端学习笔记 --ES6新特性

    前言 这篇博客是我在b站进行学习es6课程时的笔记总结与补充. 此处贴出up主的教程视频地址:深入解读ES6系列(全18讲) 1.ES6学习之路 1.1 ES6新特性 1. 变量 2. 函数 3. 数 ...

  7. ES6笔记(5)-- Generator生成器函数

    系列文章 -- ES6笔记系列 接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术. 在异步编程中,还 ...

  8. 轻松学会ES6新特性之生成器

    生成器虽然是ES6最具魔性的新特性,但也是最难懂得的一节,笔者写了大量的实例来具体化这种抽象的概念,能够让人一看就懂,目的是希望别人不要重复或者减少笔者学习生成器的痛苦经历. 在说具体的ES6生成器之 ...

  9. ES6新特性(函数默认参数,箭头函数)

    ES6新特性之 函数参数的默认值写法 和 箭头函数. 1.函数参数的默认值 ES5中不能直接为函数的参数指定默认值,只能通过以下的变通方式:   从上面的代码可以看出存在一个问题,当传入的参数为0或者 ...

随机推荐

  1. javascript 简略

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 阿里云 FTP 无法读取目录问题

    安全组除了添加制定 FTP端口外 需要加入再添加1024/65535端口 放行策略,ftp被动模式需要随机开一个此范围端口进行传输 添加安全组规则参考文档:https://help.aliyun.co ...

  3. Java知多少(52)内置异常

    在标准包java.lang中,Java定义了若干个异常类.前面的例子曾用到其中一些.这些异常一般是标准类RuntimeException的子类.因为java.lang实际上被所有的Java程序引入,多 ...

  4. Git -- 自定义git样式

    在安装Git一节中,我们已经配置了user.name和user.email,实际上,Git还有很多可配置项. 比如,让Git显示颜色,会让命令输出看起来更醒目: $ git config --glob ...

  5. Ubuntu下安装和使用zookeeper和kafka

    1.在清华镜像站下载kafka_2.10-0.10.0.0.tgz 和 zookeeper-3.4.10.tar.gz 分别解压到/usr/local目录下 2.进入zookeeper目录,在conf ...

  6. [Tensorflow] Object Detection API - predict through your exclusive model

    开始预测 一.训练结果 From: Testing Custom Object Detector - TensorFlow Object Detection API Tutorial p.6 训练结果 ...

  7. "佛祖保佑 永无bug" 注释模板设置详解(仅供娱乐)

    1.注释模板效果图 今天在网上看到一段有趣的注释,佛祖保佑 永无bug, 效果如下图所示:  代码如下所示: /** * _ooOoo_ * o8888888o * 88" . " ...

  8. 5 -- Hibernate的基本用法 --5 2 持久化对象的状态

    1. 瞬态 : 对象有new操作符创建,且尚未与Hibernate Session关联的对象被认为处于瞬态.瞬态对象不会被持久化到数据库中,也不会被赋予持久化标识.如果程序中失去了瞬态对象的引用,瞬态 ...

  9. ElasticSearch(一)-- 简介

    ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apach ...

  10. mac环境变量

    环境: 当前已经有 .bash_profile文件了 打开.bash_profile: open -e .bash_proile open -e .bash_profile 查看node安装路径: w ...