ES6基础知识(Generator 函数)
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方法的时候,屏幕上会有输出,这是因为函数foo的return语句,向函数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,就是将构造函数调用以后,这个F.prototype就是 Generator 函数的实例对象了obj换成F.prototype,再将F改成构造函数,就可以对它执行new命令了,
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 函数)的更多相关文章
- 转: ES6异步编程:Generator 函数的含义与用法
转: ES6异步编程:Generator 函数的含义与用法 异步编程对 JavaScript 语言太重要.JavaScript 只有一根线程,如果没有异步编程,根本没法用,非卡死不可. 以前,异步编程 ...
- ES6中的Generator函数
今天小编发现一个es6中的新概念,同时也接触到了一个新关键字yeild,下面我就简单和大家聊聊es6中的generator函数.大家还可以关注我的微信公众号,蜗牛全栈. 一.函数声明:在functio ...
- ES6基础知识(Generator 函数应用)
1.Ajax 是典型的异步操作,通过 Generator 函数部署 Ajax 操作,可以用同步的方式表达 function* main() { var result = yield request(& ...
- ES6基础知识(async 函数)
1.async 函数是什么?一句话,它就是 Generator 函数的语法糖. const fs = require('fs'); const readFile = function (fileNam ...
- ES6 - Note7:Generator函数
Generator函数 1.Generator函数是ES6增加的异步编程解决方案之一,与普通的函数行为完全不同,类似于一个状态机,内部封装了多个状态. 在函数定义的形式上,跟普通函数差不多,有两处不同 ...
- ES6入门之Generator函数
Generator Generator函数是ES6提供的一种异步编程解决方案,Generator函数是一个状态机,封装了多个内部状态. 执行Generator函数会返回一个遍历器对象,也就是说,Gen ...
- es6基础知识
1.超引用:(...) 用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中 function fun(...args){ console.log(args); //[1,2,3,4,5,6] ar ...
- php面试笔记(5)-php基础知识-自定义函数及内部函数考点
本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而函数相关的考点 ...
- [C/C++基础知识] main函数的参数argc和argv
该篇文章主要是关于C++\C语言最基础的main函数的参数知识,是学习C++或C语言都必备的知识点.不知道你是否知道该知识?希望对大家有所帮助.一.main()函数参数通常我们在写主函数时都是void ...
随机推荐
- 用SpringBoot实现策略模式
问题的提出 阅读别人代码的时候最讨厌遇到的就是大段大段的if-else分支语句,一般来说读到下面的时候就忘了上面在判断什么了.很多资料上都会讲到使用策略模式来改进这种代码逻辑. 策略模式的类图如下: ...
- 工作日常-SQL不能乱写
前言:刚接手别人的项目没多久,在昨天的一次上线中无故躺坑,且该大兄弟已经离职,不得不帮他填坑,整完后,今天想搞一个总结,结论就是:SQL不能乱写. 搜索关键词:Cause: java.sql.SQLE ...
- xshell连接vmware系统完整版
设置静态ip需要修改文件一共有两个要修改的文件vi /etc/resolv.confvi /etc/sysconfig/network-scripts/ifcfg-eno16777736 第一个文件 ...
- 👊 Spring技术原理系列(7)带你看看那些可能你还不知道的Spring特性技巧哦!
前提介绍 本文主要介绍相关Spring框架的一些新特性问题机制,包含了一些特定注解方面的认识. @Lazy可以延迟依赖注入 @Lazy注解修饰在类层面! @Lazy @Service public c ...
- Docker 常见命令
Docker 运行流程 辅助命令 # 1.安装完成辅助命令 docker version -------------------------- 查看docker的信息 docker info ---- ...
- Java(45)JDK新特性之String流
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201671.html 博客主页:https://www.cnblogs.com/testero ...
- iostream 操作符
iostream 操作符 Input/output manipulators - cppreference.com
- 机器学习:SVM
SVM 前言:支持向量机(Support Vector Machine, SVM),作为最富盛名的机器学习算法之一,其本身是一个二元分类算法,为了更好的了解SVM,首先需要一些前提知识,例如:梯度下降 ...
- UltraSoft - Alpha - Postmortem 事后分析
Alpha阶段 Postmortem会议 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 主要是解决DDL提醒功能的问题,定义的比较清楚,对典型用户和典 ...
- [源码解析] Pytorch 如何实现后向传播 (3)---- 引擎动态逻辑
[源码解析] Pytorch 如何实现后向传播 (3)---- 引擎动态逻辑 目录 [源码解析] Pytorch 如何实现后向传播 (3)---- 引擎动态逻辑 0x00 摘要 0x01 前文回顾 0 ...