关于javascript:ES6-系列八Iterator

30次阅读

共计 2786 个字符,预计需要花费 7 分钟才能阅读完成。

“Code tailor”,为前端开发者提供技术相干资讯以及系列根底文章,微信关注“小和山的菜鸟们”公众号,及时获取最新文章。

前言

在开始学习之前,咱们想要告诉您的是,本文章是对阮一峰《ECMAScript6 入门》一书中 “Iterator” 章节的总结,如果您已把握上面常识事项,则可跳过此环节间接进入题目练习

  • 什么是 Iterator?有何作用?
  • Iterator 是如何遍历的?
  • 默认的 Iterator 的接口和罕用场合有哪些?

如果您对某些局部有些忘记,👇🏻 曾经为您筹备好了!

学习链接

Iterator 的学习

汇总总结

概念和作用

JavaScript 示意“汇合”的数据结构,次要是数组(Array)、对象(Object),Map Set。用户能够组合应用它们,定义本人的数据结构,比方数组的成员是 MapMap 的成员是对象。这样就须要一种对立的接口机制,来解决所有不同的数据结构。

遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供对立的拜访机制。任何数据结构只有部署 Iterator 接口,就能够实现遍历操作(即顺次解决该数据结构的所有成员)。

作用:

  • 为各种数据结构,提供一个对立的、简便的拜访接口
  • 使得数据结构的成员可能按某种秩序排列
  • ES6 发明了一种新的遍历命令 for...of 循环,Iterator 接口次要供 for...of 进行遍历循环。

遍历过程

  1. 创立一个指针对象,指向以后数据结构的起始地位。也就是说,遍历器对象实质上,就是一个指针对象。
  2. 第一次调用指针对象的 next 办法,能够将指针指向数据结构的第一个成员。
  3. 第二次调用指针对象的 next 办法,指针就指向数据结构的第二个成员。
  4. 一直调用指针对象的 next 办法,直到它指向数据结构的完结地位。

默认 Iterator 接口

Iterator 接口的目标,就是为所有数据结构,提供了一种对立的拜访机制,即 for...of 循环。当应用 for...of 循环遍历某种数据结构时,该循环会主动去寻找 Iterator 接口。一种数据结构只有部署了 Iterator 接口,咱们就称这种数据结构是“可遍历的”。

在 ES6 中有以下几个数据结构具备原生的 Iterator 接口,也就是说,这些数据结构能够间接调用 for...of 进行遍历

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

除了下面这些数据结构,如果须要在别的数据结构中(次要为 Object)调用 for...of,则须要本人在 Symbol.iterator 属性下面部署,这样才会被 for...of 循环遍历。定义形式举例如下:

const obj = {[Symbol.iterator]: function () {
    return {next: function () {
        return {
          value: 1,
          done: true,
        }
      },
    }
  },
}

调用 Iterator 的罕用场合

  • 解构赋值
let set = new Set().add('a').add('b').add('c')

let [x, y] = set
// x='a'; y='b'

let [first, ...rest] = set
// first='a'; rest=['b','c']
  • 扩大运算符
// 例一
var str = 'hello'
[...str] //  ['h','e','l','l','o']

// 例二
let arr = ['b', 'c']
['a', ...arr, 'd']
// ['a', 'b', 'c', 'd']
  • yield*
let generator = function* () {
  yield 1
  yield* [2, 3, 4]
  yield 5
}

var iterator = generator()

iterator.next() // { value: 1, done: false}
iterator.next() // { value: 2, done: false}
iterator.next() // { value: 3, done: false}
iterator.next() // { value: 4, done: false}
iterator.next() // { value: 5, done: false}
iterator.next() // { value: undefined, done: true}

理解遍历器如何写

遍历器对象除了具备 next() 办法,还能够具备 return() 办法和 throw() 办法。如果你本人写遍历器对象生成函数,那么 next() 办法是必须部署的,return() 办法和 throw() 办法是否部署是可选的。

/*
return() 办法的应用场合是,如果 for...of 循环提前退出(通常是
因为出错,或者有 break 语句),就会调用 return() 办法。如果一个对
象在实现遍历前,须要清理或开释资源,就能够部署 return() 办法。*/
function readLinesSync(file) {
  return {[Symbol.iterator]() {
      return {next() {return { done: false}
        },
        return() {file.close()
          return {done: true}
        },
      }
    },
  }
}

题目自测

一: for in 和 for of 的区别


二: 以下代码会输入什么()

const obj = {2: 5, 3: 6, 4: 7}
obj[Symbol.iterator] = function () {
  return {next: function () {if (this._countDown === 3) {return { value: this._countDown, done: true}
      }
      this._countDown = this._countDown + 1
      return {value: obj[this._countDown], done: false }
    },
    _countDown: 0,
  }
}
for (const i of obj) {console.log(i)
}
  • A. 2,3,4
  • B. 5,6,7
  • C. undefined,5,6
  • D. TypeError: obj is not iterable

题目解析

一、

Answer:

正确答案及解析:

for…in for…of
Applies to Enumerable Properties Iterable Collections
Use with Objects? Yes No
Use with Arrays? Yes, but not advised Yes
Use with Strings? Yes, but not advised Yes

二、

Answer:(C)

obj 是一个一般对象,失常遍历会报错如 D,但下面代码中增加了 Symbol.iterator 属性,所以能够遍历,遍历时看 return 的值为 obj[this._countDown],及把每次遍历次数当做键名取值,能够看失去,obj 中只有 2,3,4 这三个键名的键,所以第一次取到的是 undefined,前面失去 5 和 6 所以选 C

正文完
 0