javascript 生成器函数 function*

今天看了一下这块的东西,文档不是很好理解。但是完完整整看下来,文档还是很全的。

这里算是总结一下在看生涩的文档之前可以了解的东西,方便看文档的时候好理解。

1,什么是生成器函数(function*)

生成器函数简单理解就是这个函数返回一个可枚举的对象(官方说法返回Generator  对象)。可以通过.next()枚举其中的数据。内部通过yield关键字实现步进。

2,为什么要有一个生成器函数(function*)这种特殊的语法,

C#也有yield,但是并没有特殊的语法。下面链接是es委员会一员的回答。https://stackoverflow.com/questions/27778105/whats-the-purpose-of-an-asterisk-in-es6-generator-functions/27787527

说实话,第二条没在看懂。就感觉是弱类型语言的毛病。

3,看迭代器和生成器这部分是看到,“传给第一个 next() 的值会被忽略”,为什么。

其实生成器函数文档中已经有说明,“调用 next()方法时,如果传入了参数,那么这个参数会传给上一条执行的 yield语句左边的变量”。下面我们通过一段代码理解一下。

function* countAppleSales () {
  console.log("生成器函数第一行代码");
  var saleList = [0,1,2,3,4,5];
  for (var i = 0; i < saleList.length; i++) {
    var re =  yield saleList[i];
    console.log(`re:${re}`)
    if(re===true){ 
      i=4;
    }
  }
}


var appleStore = countAppleSales(); // 调用生成器函数不执行任何代码,而是返回迭代器。
console.log("开始调用");
console.log(appleStore.next(false)); //第一次next(),从生成器函数第一行代码开始执行,执行到第一次遇到 yield,返回 { value: 0, done: false }.
//此时传入的参数(false)没机会给“yield左边的变量”re赋值.
console.log("------------------");//分割线
console.log(appleStore.next(true)); //第二次next(),从上一次yield截断处继续执行,直到再次遇到yield。
//执行代码如下
//1,先给“yield左边的变量”re赋值,值为next()的参数,这里为true。执行打印“re:true”。后面i赋值为4,下一次循环i++,此时i为5。再次走到yield 返回{ value: 5, done: false }。


下面是最终的执行结果

开始调用
生成器函数第一行代码
{ value: 0, done: false }
------------------
re:true
{ value: 5, done: false }

看完这些再看文档,特别是翻译的中文文档应该会好点,希望对你有所帮助。

下面说一个使用场景,也是看到这里才学生成器函数的。

https://es6.ruanyifeng.com/#docs/array#%E6%89%A9%E5%B1%95%E8%BF%90%E7%AE%97%E7%AC%A6%E7%9A%84%E5%BA%94%E7%94%A8  直接看第五部分。

Number.prototype[Symbol.iterator] = function*() {
  let i = 0;
  let num = this.valueOf();
  while (i < num) {
    yield i++;
  }
}

console.log([...5]) // [0, 1, 2, 3, 4]
上面代码中,先定义了Number对象的遍历器接口,扩展运算符将5自动转成Number实例以后,就会调用这个接口,就会返回自定义的结果。

给自定义对象加枚举器

let arrayLike = { 
  arr:[0,1,2,3]
};

arrayLike[Symbol.iterator] = function*() {
  let num = this.valueOf();
  // num.arr.forEach(element => {
  //   yield element;//报错。forEach里面是传了一个函数进去,所以yield语句实际上在一个不是生成器的函数里面,所以报错。
  // });

  for(let item of num.arr){
    yield item;
  }
 
}


console.log([...arrayLike]);

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值