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 ...
随机推荐
- vector 的交换技巧
面试被问到如何解决 vector 有过多空闲内存的问题. 假定先有一 vector 容器 vec,它的容量是 10000,大小是 3. vector 的内存增长问题 vector 申请的是连续内存空间 ...
- Java中的原子操作
Java中的原子操作 原子性:指该操作不能再继续划分为更小的操作. Java中的原子操作包括: 除long和double之外的基本类型的赋值操作 所有引用reference的赋值操作 java.con ...
- SpringBoot之网站的登陆注册逻辑
网站的登录注册实现逻辑 该文章主要是为了整理之前学习项目中的知识点,并进行一定程度的理解. 技术列表: SpringBoot MySQL redis JWT 用户登录逻辑: 首先打开前端登录页面,F1 ...
- 基于querybuilder的可根据现有数据表自动生成Restful API的dotnet中间件
AutoApi 基于SqlKata Query Builder的可根据数据表自动生成Restful API的dotnet中间件 项目地址 Github Gitee 支持的数据库 MySql AutoA ...
- 每日总结:Java课堂测试第三阶段第二次优化 (四则运算) (2021.9.22)
package jisuan2; import java.util.*;import java.util.Scanner; public class xiaoxue { public static v ...
- NOI 2017 Day1 题解
被虐爆了... T1 整数 题目传送门 Description 有一个整数 \(x\),有 \(n\) 此操作,每次操作为以下两种情况: 给出 \(a,b\),将 \(x\) 加上 \(a\times ...
- allure报告中allure.title 如何去掉后方的参数化显示
1.解决方法如下 listener.py 文件位置:Lib\site-packages\allure_pytest\listener.py (第三方包所在的LIb目录) 将下图中红色部分test_re ...
- 脚本注入3(blind)
布尔盲注适用于任何情况回显都不变的情况. (由此,可以看出,回显啥的其实都不重要,最重要的是判断注入点.只要找到注入点了,其他的都是浮云.) 在操作上,时间盲注还稍微简单一点:它不需要像布尔盲注那样, ...
- 【c++ Prime 学习笔记】第17章 标准库特殊设施
17.1 tuple类型 tuple是类似pair的模板: pair和tuple的成员类型都可以不相同 pair恰好有两个成员,tuple可有任意数量的成员 按照不同参数数量和类型实例化出的tuple ...
- 51.N皇后问题
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 给定一个整数 n,返回所有不同的 n 皇后问题的解决方案. 每一种解法包含一个明确的 n 皇后问题的棋 ...