迭代器、生成器

简介: JS查漏补缺系列是我在学习JS高级语法时做的笔记,通过实践费曼学习法进一步加深自己对其的理解,也希望别人能通过我的笔记能学习到相关的知识点。这一次我们来了解JavaScript中的迭代器、生成器

迭代器

迭代器是一个对象,让我们能够遍历某个数据结构(如:链表或数组)
在JS中,迭代器是一个对象且还需要有next函数(符合迭代器协议)
const iterator = {next: function() {return {}}}

next函数

一个 无参数函数,返回一个应当拥有done和value属性的对象:

done (boolean):

  • 如果迭代器可以产生序列中的下一个值,则为 false。(这等价于没有指定 done 这个属性。)
  • 如果迭代器已将序列迭代完毕,则为 true。这种情况下,value 是可选的,如果它依然存在,即为迭代结束之后的默认返回值。

value:迭代器返回的任何 JavaScript 值。done 为 true 时可省略。

// 数组
const names = ["abc", "cba", "nba"]

// 创建一个迭代器对象来访问数组
let index = 0
const namesIterator = {
  next: function() {
    if (index < names.length) {
      return { done: false, value: names[index++] }
    } else {
      return { done: true, value: undefined }
    }
  }
}

console.log(namesIterator.next())
console.log(namesIterator.next())

可迭代对象

可迭代对象是一个对象且需要实现 @@iterator方法,我们可以使用Symbol.iterator访问该属性(符合可迭代协议)
const iterableObj = {[Symbol.iterator]: function(){return 迭代器}}
const iterableObj = {
  names: ["abc", "cba", "nba"],
  [Symbol.iterator]: function() {
    let index = 0
    return {
      next: () => {  // 使用箭头函数使this指向iterableObj
        if (index < this.names.length) {
          return { done: false, value: this.names[index++] }
        } else {
          return { done: true, value: undefined }
        }
      }
    }
  }
}

用于可迭代对象的语法:

  1. for ...of 可以遍历的东西必须是一个可迭代对象
  2. 展开运算符 (...) [ 在ES9之后新增的特性:普通对象也可以使用展开运算符 ]
  3. 解构赋值 [ 在ES9之后新增的特性:普通对象也可以使用解构赋值]
  4. yield*
  5. 使用Set 、Array.from 创建对象时需要传入可迭代对象

内置可迭代对象

String、Array、TypedArray、Map 和 Set 都是内置可迭代对象,因为它们的原型对象都拥有一个 Symbol.iterator 方法

// 以数组为例:
const names = ["abc", "cba", "nba"]
console.log(names[Symbol.iterator])

生成器

与函数相关,是ES6新增的一种函数控制、使用的方案(控制函数什么时候继续执行、暂停执行等操作)
生成器函数返回值是一个生成器

生成器函数

生成器函数特点:

  • 生成器函数需要在function的后面加一个符号:*
  • 生成器函数可以通过yield关键字来控制函数的执行流程
  • 生成器函数的返回值是一个Generator(生成器)
function* foo() {
  console.log("函数开始执行~")

  const value1 = 100
  console.log("第一段代码:", value1)
  yield

  const value2 = 200
  console.log("第二段代码:", value2)
  yield

  console.log("函数执行结束~")
}

// 调用生成器函数时, 会给我们返回一个生成器对象
const generator = foo()

// 开始执行第一段代码
generator.next()

我们使用第一个next()调用的时候,执行的是第一个yield上面的代码

  • 当遇到yield时候值暂停函数的执行
  • 当遇到return时候生成器就停止执行
  • 如果想要第一个next返回的结果不是undefined,则在yield之后加上想要返回的值:yield value1

生成器本质上是一个特殊的迭代器

//打印的结果与迭代器的形式是一样的
const generator = foo()
console.log("返回值:", generator.next())
// 返回值: { value: undefined, done: false }

生成器的方法使用

next传递参数

我们在调用next函数的时候,可以给它传递参数,那么这个参数会作为上一个yield语句的返回值;而这个传递进来的参数则为下一个代码块执行提供了一个值
function* foo(num) {
  console.log("函数开始执行~")

  const value1 = 100 * num
  console.log("第一段代码:", value1)
  const n = yield value1

  const value2 = 200 * n
  console.log("第二段代码:", value2)

  console.log("函数执行结束~")
  return "123"
}

// 生成器上的next方法可以传递参数
//给第一个代码块传参
const generator = foo(5)  // 传入的5被上面的num接收
generator.next()
// 给第二个代码块传参,传入的10对应上面的n
generator.next(10)

return终止执行

// 相当于在代码块的后面加上return, 就会提前终端生成器函数代码继续执行
generator.return(15)

用生成器替代迭代器

// 原先用迭代器实现:
function createArrayIterator(arr) {
  let index = 0
  return {
    next: () => {  
      if (index < arr.length) {
         return { done: false, value: arr[index++] }
      } else {
        return { done: true, value: undefined }
      }
    }
  }
}
因为生成器是特殊的迭代器,所以我们可以用生成器去简化代码:
function* createArrayIterator(arr) {
  for (const item of arr) {
    yield item
  }
}

yield*

yield*是一种yield的语法糖,可以用它来生产一个可迭代对象
如下面的 yield* arr ,这个代码会依次迭代 arr 这个可迭代对象,每次迭代其中的一个值
function* createArrayIterator(arr) {
  yield* arr
}
目录
相关文章
|
7月前
|
算法 前端开发
2649. 嵌套数组生成器
2649. 嵌套数组生成器
37 0
|
29天前
|
JavaScript 前端开发
ES6 迭代器和生成器
总的来说,ES6 迭代器和生成器为 JavaScript 提供了更强大的遍历和控制能力,使代码更加灵活和高效。
22 1
使用推导式和生成器创建数组
使用推导式和生成器可以便捷创建数组。例如,`[n^2 for n in 1:10]` 生成一个包含平方数的向量,而 `[n*m for n in 1:10, m in 1:10]` 创建一个乘积矩阵。无括号形式如 `n^2 for n in 1:5` 产生生成器,需要 `collect` 转换为数组。另外,表达式 `sum(1/n^2 for n=1:1000)` 求和而不占用大量内存。
|
7月前
|
大数据 Python
Python编程中的迭代器与生成器
【2月更文挑战第7天】在Python编程中,迭代器和生成器是两个重要的概念,它们提供了一种高效的方法来处理数据集合。本文将深入探讨迭代器和生成器的定义、用法以及在实际项目中的应用,帮助读者更好地理解和运用这两个功能强大的工具。
【面向对象的三大特征以及迭代器生成器】
【面向对象的三大特征以及迭代器生成器】
38 0
|
JavaScript 前端开发
迭代器和生成器
在JavaScript中,迭代器(`Iterator`)是一个对象,用于在可迭代的数据结构中遍历和访问每个元素,而不必暴露该数据结构的内部结构。
|
存储 Python
18.从入门到精通:Python迭代器与生成器 迭代器 创建一个迭代器 StopIteration 生成器
18.从入门到精通:Python迭代器与生成器 迭代器 创建一个迭代器 StopIteration 生成器
|
Python
生成器和迭代器
生成器和迭代器
58 0