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

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

image.png


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

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


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


正文



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


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;
   }
}


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


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 };
           }
       }
     };
   }
}


所以,生成器应运而生。


function* generatorFn() {
 return 'foo';
}
const g = generatorFn();
console.log(g === g[Symbol.iterator]()); // true


可以看到:


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


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


// 生成器函数
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 关键字可以将跟在它后面的可迭代对象序列化为一连串值。


相关文章
|
7月前
|
前端开发 JavaScript 中间件
掌握JavaScript中的迭代器和生成器(下)
掌握JavaScript中的迭代器和生成器(下)
|
7月前
|
存储 JavaScript 前端开发
掌握JavaScript中的迭代器和生成器(上)
掌握JavaScript中的迭代器和生成器
106 0
|
6月前
|
存储 JavaScript 前端开发
javascript中的生成器和迭代器是什么
JavaScript中的生成器和迭代器是处理集合数据的利器,它们提供了一种遍历和操作元素的统一方式。迭代器是具有`next()`方法的对象,返回包含`value`和`done`属性的对象,用于循环处理集合。生成器函数更进一步,可以在执行过程中暂停并返回值,通过`yield`产生迭代值,适用于生成序列、异步编程和实现状态机等场景。例如,一个生成器可以无限生成斐波那契数列,或者在读取文件时控制异步流程。使用这些工具,代码变得更简洁、高效。
|
3月前
|
JavaScript 前端开发 Python
JavaScript写个.ts视频文件Url生成器,使用了string.padStart
JavaScript写个.ts视频文件Url生成器,使用了string.padStart
|
4月前
|
存储 JavaScript 算法
JS程序设计的常用套路
亲尝百草,方知甘苦。套路,通常有助于提升代码的可读性、扩展性和效率。以下是作者工作中总结出来的一部分代码套路,分享给大家。
|
5月前
|
存储 JavaScript 前端开发
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(二)
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(二)
60 1
|
6月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的计算机网络课程试卷生成器附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的计算机网络课程试卷生成器附带文章和源代码部署视频讲解等
42 2
|
5月前
|
存储 JavaScript 前端开发
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(一)
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(一)
44 0
|
6月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的程序设计基础视频学习系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的程序设计基础视频学习系统附带文章和源代码部署视频讲解等
40 0
|
7月前
|
存储 JavaScript 前端开发
JavaScript中的复杂功能实现:一个动态表单生成器
JavaScript中的复杂功能实现:一个动态表单生成器