Generator
函数
yield*
表达式
如果在 generator
函数内部调用另一个 generator
函数,默认情况下是没有效果的。
yield*
后面的 Generator
函数(没有 return
语句时)等同于在 generator
函数内部部署 for...of
循环
// 定义generator函数
function* ickt(){
yield 1;
yield 2;
}
function* demo(){
yield "ljh";
yield "ljh1";
// 直接执行 ickt
// ickt();// 无效
// yield ickt();// ['ljh','ljh','ickt']
//返回状态机中的状态
// let i= ickt();
// for(let item of i){
// console.log(item)
// yield item;
// }
// yield*表达式
yield* ickt();
yield "12";
}
let d = demo();
console.log([...d])
yield*
后面跟着 个数组,由于数组原生支持遍历器,因此就会遍历数组成员
任何数据结构只要有 Iterator
接口,就可以被 yield*
遍历
// 定义generator函数
function* ickt(){
yield 1;
yield 2;
// 将函数内部的数据 传递给yield*表达式或者其他的变量 内部向外部传递数据
// next 方法 外部向内部传递数据
return "ljh"
}
function* demo(){
yield "ljh";
yield "ljh1";
// 直接执行 ickt
// ickt();// 无效
// yield ickt();// ['ljh','ljh','ickt']
//返回状态机中的状态
// let i= ickt();
// for(let item of i){
// console.log(item)
// yield item;
// }
// yield*表达式
// yield* ickt();
// yield "12";
// yield* 只要实现便利器接口的数据都可以
// yield* [1,2,3];
// yield* arguments; //获取传递的参数
// yield* "lijh";
// yield* 不会遍历return的数据
let retsult = yield* ickt();
console.log(retsult)
}
let d = demo(1,3,4,5,6);
console.log([...d])
如果被代理的 generator
函数有 return
语句,那么便可以向代理它的 generator
函数返回数据。
//数组降维、
let arr = ['a', ['b', ['c', ['d', 'e', ['f'], 'g'], ['h']]], 'i'];
// console.log(arr.flat(5))
// 第一种方式
// function dealArray(arr){
// return arr.map(item=>{
// if(Array.isArray(item)){
// return dealArray(item.flat())
// }
// return item
// }).flat()
// }
// console.log(dealArray(arr))
//第二种方式
// function dealArray(arr){
// return arr.map(item=>{
// if(Array.isArray(item)){
// return dealArray(item.flat())
// }
// return item
// }).flat()
// }
// function* deal(){
// for(let item of dealArray(arr)){
// yield item
// }
// }
// console.log([...deal()])
//第三种方式
function* deaaArr(arr){
//遍历成员
for(let item of arr){
//判断数组
if(Array.isArray(item)){
yield* deaaArr(item)
}else{
yield item
}
}
}
console.log([...deaaArr(arr)])
二叉树
// 'a'
// 'b' 'c'
// 'd' 'e' 'f' 'g'
// 'h' 'i' 'j' 'k'
// 定义数组
let arr = [[[['h'], 'd', ['i']], 'b', ['e']], 'a', [[['j'], 'f', ['k']], 'c', ['g']]]
// 定义树类
function Tree(left, center, right) {
// 存储
// this.left = left;
// this.center = center;
// this.right = right;
// 简化
Object.assign(this, { left, center, right })
}
// 属性没有名字
// function Tree(...arg) {
// Object.assign(this, { ...arg })
// }
// 测试
// console.log(new Tree('a', 'b', 'c'));
// 转化方法
function deal(arr) {
// 只有叶子节点
if (arr.length === 1) {
return new Tree(null, arr[0], null)
}
return new Tree(deal(arr[0]), arr[1], deal(arr[2]))
}
let tree = deal(arr);
// 将节点变成状态
function* ickt(t) {
t.left && (yield* ickt(t.left));
yield t.center;
t.right && (yield* ickt(t.right));
}
// console.log([...ickt(tree)])
let demo = ickt(tree);
console.log(demo.next())
console.log(demo.next())
console.log(demo.next())
console.log(demo.next())
console.log(demo.next())
yield*
命令可以很方便地取出嵌套数组的所有成员
this
指向
generator
函数总是返回一个遍历器对象。 ES6
规定这个遍历器是 generator
函数的实例 ,它也继承了 generator
函数的 prototype
对象上的方法,如 next
,return
,throw
等方法
如果把 generator
函数当作普通的构造函数,则并不会生效,
因为它返回的总是遍历器对象,而不是 this
对象。
generator
函数也不能跟new 命令一起起用,否则会报错。
可以通过
call
、apply
、bind
等方法更改generator
函数运行的上下文对象,此时this
指向该对象
我们也可以将 generator
函数作为对象的属性方法,在对象字面量中,可以省略 function
关键字,直接在函数名称前面加 *
号。
// 定义generator函数
function* demo() {
// console.log(this, 111)
// 不能通过this存储数据
this.color = 'red';
yield 1;
// 分阶段拓展数据
this.width = 10;
yield 2;
this.height = 20;
}
// 原型方法
// demo.prototype.num = 10;
Object.assign(demo.prototype, {
num: 20,
msg: 'hello',
getMsg() {
console.log(this.msg)
}
})
// let d = demo()
// 不能使用new关键字
// let d = new demo()
// // 可以更改上下文环境
// let obj = { title: 'ickt' };
// // let d = demo.call(obj);
// // 让demo在原型对象上运行,此时this指向原型对象,数据被添加到原型对象上,
// let d = demo.call(demo.prototype)
// // 执行next方法,才能启动demo
// d.next();
// console.log(d, obj)
// console.log(d.color)
// console.log(d.title)
// d.getMsg()
// 普通函数运行完毕,没有结果,无法获取原型上的数据
// function ickt() {}
// ickt.prototype.num = 20;
// console.log(ickt());
封装generator函数类
// 定义generator函数
function* demo() {
// console.log(this, 111)
// 不能通过this存储数据
this.color = 'red';
yield 1;
// 分阶段拓展数据
this.width = 10;
yield 2;
this.height = 20;
}
// 原型方法
// demo.prototype.num = 10;
Object.assign(demo.prototype, {
num: 20,
msg: 'hello',
getMsg() {
console.log(this.msg)
}
})
function dealDemo(fn){
//安全检测
if (Object.prototype.toString.call(fn) === "[object GeneratorFunction]") {
// 在generator函数中,通过this存储数据
return fn.call(fn.prototype)
}
throw new Error('必须传递generator函数')
}
let dd = new dealDemo(demo)
console.log(dd.next())
console.log(dd.color)
console.log(dd.width)
对象添加generator函数
let obj = {
// 普通函数可以简写,generator函数也可以简写
// test: function* () {
// yield 1;
// }
* test() {
yield 5;
}
}
console.log(obj.test().next())
来源:oschina
链接:https://my.oschina.net/u/4162046/blog/3220730