前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅习一波JavaScript高级程序设计(第4版)p7-生成器

浅习一波JavaScript高级程序设计(第4版)p7-生成器

作者头像
掘金安东尼
发布2022-09-19 10:42:12
2250
发布2022-09-19 10:42:12
举报
文章被收录于专栏:掘金安东尼

theme: smartblue

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情


JavaScript 高级程序设计第 4 版(后简称高程4),相较于第 3 版,增加了 ES6 至 ES10 的全新内容,删除了旧版过时的内容,并在原有基础上充实了更加翔实的内容。

中文译版于 2020 年发售,妥妥的“新鲜出炉”,你要是问本瓜:当今学 JavaScript 哪家强,我只能说:红宝书第 4 版最在行。

于是乎,借着更文契机,本瓜将开启一个小系列,带你重看一遍高级程序设计4(先前只是跳着跳着看),将抽取精华,用最简单的话解释核心点、尽量把握全局、快速过一遍的同时,记录与工友们分享~~

正文

生成器,说白了,就是来自定义生成:迭代器对象的。

代码语言:javascript
复制
class Counter {
     // Counter 的实例应该迭代 limit 次
     constructor(limit) {
        this.count = 1;
        this.limit = limit;
     }
     next() {
         if (this.count <= this.limit) {
                 return { done: false, value: this.count++ };
         } else {
                 return { done: true, value: undefined };
         }
     }
     [Symbol.iterator]() {
         return this;
     }
}

通过这种方式创建迭代器,太费劲儿了,并且这还只是简易版本,还不支持多次迭代,支持多次迭代的,还将用到闭包结构:

代码语言:javascript
复制
class Counter {
     constructor(limit) {
         this.limit = limit;
     }
     [Symbol.iterator]() {
        let count = 1,
        limit = this.limit;
        return {
             next() {
                     if (count <= limit) {
                             return { done: false, value: count++ };
                     } else {
                             return { done: true, value: undefined };
                     }
             }
         };
     }
}

所以,生成器应运而生。

代码语言:javascript
复制
function* generatorFn() {
 return 'foo';
}

const g = generatorFn();
console.log(g === g[Symbol.iterator]()); // true

可以看到:

g === g[Symbol.iterator]() 为 true,妥妥的,生成器就是来构造迭代器对象的最好证明!!

来看看生成器函数怎么写:

代码语言:javascript
复制
// 生成器函数
function* generator(i){
    yield i + 1
    var y = yield 'foo'
    yield y
}

var iterator = generator(10) // 此时生成器函数不执行,返回一个迭代器

iterator.next()   // {value: 11, done: false}
iterator.next()   // {value 'foo', done: false}
iterator.next(10) // {value: 10, done: false},将 10 赋值给上一条 yield 'foo' 左侧的值,即 y = 10,返回 y
iterator.next()   // {done: true}

生成器函数的语法规则是:

调用一个生成器函数并不会马上执行它里面的语句,而是返回一个这个生成器的 迭代器(iterator)对象。

当这个迭代器的 next() 方法被首次(后续)调用时,其内的语句会执行到第一个(后续)出现yield的位置为止,yield 后紧跟迭代器要返回的值。

或者如果用的是 yield*(多了个星号),则表示将执行权移交给另一个生成器函数(当前生成器暂停执行)。调用 next() 方法时,如果传入了参数,那么这个参数会作为上一条执行的 yield 语句的返回值。

其实,就把 yield 理解为一个缩小版的 return 即可;每执行一个 next,就 return 一个值,如果有赋值,则赋给上一个 return 结果里面去。

小结

高程第七章最后这一段小结,每一个字都值得认真去读:(建议背诵)

迭代器是一个可以由任意对象实现的接口,支持连续获取对象产出的每一个值。

任何实现 Iterable 接口的对象都有一个 Symbol.iterator 属性,这个属性引用默认迭代器。默认迭代器就像一个迭代器工厂,也就是一个函数,调用之后会产生一个实现 Iterator 接口的对象。

迭代器必须通过连续调用 next()方法才能连续取得值,这个方法返回一个 IteratorObject。这个对象包含一个 done 属性和一个 value 属性。前者是一个布尔值,表示是否还有更多值可以访问;后者包含迭代器返回的当前值。这个接口可以通过手动反复调用 next()方法来消费,也可以通过原生消费者,比如 for-of 循环来自动消费。

生成器是一种特殊的函数,调用之后会返回一个生成器对象。生成器对象实现了 Iterable 接口,因此可用在任何消费可迭代对象的地方。

生成器的独特之处在于支持 yield 关键字,这个关键字能够暂停执行生成器函数。使用 yield 关键字还可以通过 next()方法接收输入和产生输出。在加上星号之后,yield 关键字可以将跟在它后面的可迭代对象序列化为一连串值。

OK,以上便是本篇分享。 觉得不错点个赞吧👍👍👍,您的鼓励,我的动力,坚持原创质量好文~~ 欢迎评论留言 我是掘金安东尼,输出暴露输入,技术洞见生活。再会吧~~ 👋👋👋

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • theme: smartblue
    • 正文
      • 小结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档