1.next()、throw()、return() 的共同点

next()throw()return()这三个方法本质上是同一件事,可以放在一起理解。它们的作用都是让 Generator 函数恢复执行,并且使用不同的语句替换yield表达式。

①next()是将yield表达式替换成一个值。

const g = function* (x, y) {
let result = yield x + y;
return result;
}; const gen = g(1, 2);
gen.next(); // Object {value: 3, done: false} gen.next(1); // Object {value: 1, done: true}
// 相当于将 let result = yield x + y
// 替换成 let result = 1;

上面代码中,第二个next(1)方法就相当于将yield表达式替换成一个值1。如果next方法没有参数,就相当于替换成undefined

throw()是将yield表达式替换成一个throw语句。

gen.throw(new Error('出错了')); // Uncaught Error: 出错了
// 相当于将 let result = yield x + y
// 替换成 let result = throw(new Error('出错了'));

return()是将yield表达式替换成一个return语句。

gen.return(2); // Object {value: 2, done: true}
// 相当于将 let result = yield x + y
// 替换成 let result = return 2;

2.一个 Generator 函数里面执行另一个 Generator 函数,需要用到yield*表达式

function* foo() {
yield 'a';
yield 'b';
}

从语法角度看,如果yield表达式后面跟的是一个遍历器对象,需要在yield表达式后面加上星号,表明它返回的是一个遍历器对象。这被称为yield*表达式。


function* bar() {
yield 'x';
yield* foo();
yield 'y';
} // 等同于
function* bar() {
yield 'x';
yield 'a';
yield 'b';
yield 'y';
} // 等同于
function* bar() {
yield 'x';
for (let v of foo()) {
yield v;
}
yield 'y';
} for (let v of bar()){
console.log(v);
}
// "x"
// "a"
// "b"
// "y"

任何数据结构只要有 Iterator 接口,就可以被yield*遍历

function* gen(){
yield* ["a", "b", "c"];
} gen().next() // { value:"a", done:false } let read = (function* () {
yield 'hello';
yield* 'hello';
})(); read.next().value // "hello"
read.next().value // "h"

上面代码中,yield命令后面如果不加星号,返回的是整个数组,加了星号就表示返回的是数组的遍历器对象

上面代码中,yield表达式返回整个字符串,yield*语句返回单个字符。因为字符串具有 Iterator 接口,所以被yield*遍历

如果被代理的 Generator 函数有return语句,那么就可以向代理它的 Generator 函数返回数据

function* foo() {
yield 2;
yield 3;
return "foo";
} function* bar() {
yield 1;
var v = yield* foo();
console.log("v: " + v);
yield 4;
} var it = bar(); it.next()
// {value: 1, done: false}
it.next()
// {value: 2, done: false}
it.next()
// {value: 3, done: false}
it.next();
// "v: foo"
// {value: 4, done: false}
it.next()
// {value: undefined, done: true}

上面代码在第四次调用next方法的时候,屏幕上会有输出,这是因为函数fooreturn语句,向函数bar提供了返回值。

yield*命令可以很方便地取出嵌套数组的所有成员

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

3.Generator 函数的this

生成一个空对象,使用call方法绑定 Generator 函数内部的this,就是将obj换成F.prototype,再将F改成构造函数,就可以对它执行new命令了,构造函数调用以后,这个F.prototype就是 Generator 函数的实例对象了

function* gen() {
this.a = 1;
yield this.b = 2;
yield this.c = 3;
} function F() {
return gen.call(gen.prototype);
} var f = new F(); f.next(); // Object {value: 2, done: false}
f.next(); // Object {value: 3, done: false}
f.next(); // Object {value: undefined, done: true} f.a // 1
f.b // 2
f.c // 3

备注:文中多数内容摘自阮一峰老师文章,仅供自我学习查阅。

ES6基础知识(Generator 函数)的更多相关文章

  1. 转: ES6异步编程:Generator 函数的含义与用法

    转: ES6异步编程:Generator 函数的含义与用法 异步编程对 JavaScript 语言太重要.JavaScript 只有一根线程,如果没有异步编程,根本没法用,非卡死不可. 以前,异步编程 ...

  2. ES6中的Generator函数

    今天小编发现一个es6中的新概念,同时也接触到了一个新关键字yeild,下面我就简单和大家聊聊es6中的generator函数.大家还可以关注我的微信公众号,蜗牛全栈. 一.函数声明:在functio ...

  3. ES6基础知识(Generator 函数应用)

    1.Ajax 是典型的异步操作,通过 Generator 函数部署 Ajax 操作,可以用同步的方式表达 function* main() { var result = yield request(& ...

  4. ES6基础知识(async 函数)

    1.async 函数是什么?一句话,它就是 Generator 函数的语法糖. const fs = require('fs'); const readFile = function (fileNam ...

  5. ES6 - Note7:Generator函数

    Generator函数 1.Generator函数是ES6增加的异步编程解决方案之一,与普通的函数行为完全不同,类似于一个状态机,内部封装了多个状态. 在函数定义的形式上,跟普通函数差不多,有两处不同 ...

  6. ES6入门之Generator函数

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

  7. es6基础知识

    1.超引用:(...) 用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中 function fun(...args){ console.log(args); //[1,2,3,4,5,6] ar ...

  8. php面试笔记(5)-php基础知识-自定义函数及内部函数考点

    本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而函数相关的考点 ...

  9. [C/C++基础知识] main函数的参数argc和argv

    该篇文章主要是关于C++\C语言最基础的main函数的参数知识,是学习C++或C语言都必备的知识点.不知道你是否知道该知识?希望对大家有所帮助.一.main()函数参数通常我们在写主函数时都是void ...

随机推荐

  1. 解决VM 与 Device/Credential Guard 不兼容

    通过命令关闭Hyper-V(控制面板关闭Hyper-V起不到决定性作用,要彻底关闭Hyper-V) 以管理员身份运行Windows Powershell (管理员)(Windows键+X) 运行下面命 ...

  2. spark性能优化(一)

    本文内容说明 初始化配置给rdd和dataframe带来的影响 repartition的相关说明 cache&persist的相关说明 性能优化的说明建议以及实例 配置说明 spark:2.4 ...

  3. for...in和Object.keys()区别

    区别: for in 用来枚举对象的属性,某些情况下,可能按照随机顺序遍历数组元素 object.keys() 可以返回对象属性为元素的数组,数组中属性名顺序和for in比那里返回顺序一样 ---f ...

  4. 初始HTML03

    **------------恢复内容开始------------** HTML 页面标签组成 一个完整的页面仅有一个html元素,在这个元素之下,包含head和body元素,前者负责说明页面结构,后者 ...

  5. Vue CLI 5 和 vite 创建 vue3.x 项目以及 Vue CLI 和 vite 的区别

    这几天进入 Vue CLI 官网,发现不能选择 Vue CLI 的版本,也就是说查不到 vue-cli 4 以下版本的文档. 如果此时电脑上安装了 Vue CLI,那么旧版安装的 vue 项目很可能会 ...

  6. cs224n 2019

    视频链接 相关资源 Notes 笔记下载 笔记2 需要挂梯子,不然不显示图片,如果用ssr,要调到全局模式 转自:bitJoy CS224N(1.8)introduction and Word Vec ...

  7. Noip模拟6 2021.6.10

    T1 辣鸡 首先吐嘈一下,这题的测试点就离谱,不说了,附上我65分代码: 1 #include<bits/stdc++.h> 2 #define int long long 3 using ...

  8. WiFi模块选型参考

    经常会碰到一些关于wifi模块的咨询,很多刚接触wifi模块的设计人员或者用户,只知道提wifi模块,很难提具体的模块要求!希望通过文章的介绍,会做到有的放矢!咨询时一定要搞清楚自己希望使用什么主芯片 ...

  9. MD5函数(公共方法)

    1 #region MD5函数 2 /// <summary> 3 /// MD5函数 4 /// </summary> 5 /// <param name=" ...

  10. Python import Queue ImportError: No module named 'Queue'

    python3 中引入Queue 会报出这个问题 python3 中这样引入 import queue python2 中这样引入 import Queue 为了兼容 可以这样 import sys ...