遍历器
Iterator
用于遍历数据结构的机制,它定义了一种统一的方式来访问集合中的每个元素,任何数据接口只要部署 Iterator,就可以完成遍历操作
- 为各种数据结构,提供一个统一的、简便的访问接口
- 使得数据结构的成员能够按某种次序排列
- ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供
for...of
...
Array.from()
消费
原生具备 Iterator 接口数据类型: Array、String、Map、Set、TypeArray、NodeList
对象没有部署 Iterator 接口
调用遍历器
js
const arr = [10, 11, 12]
const iterator = arr[Symbol.iterator]()
iterator.next() // {value: 10, done: false}
iterator.next() // {value: 11, done: false}
// ...
iterator.next() // {value: undefined, done: true}
const arr = [10, 11, 12]
const iterator = arr[Symbol.iterator]()
iterator.next() // {value: 10, done: false}
iterator.next() // {value: 11, done: false}
// ...
iterator.next() // {value: undefined, done: true}
利用遍历器实现"链表"
js
function Obj(value) {
this.value = value
this.next = null
}
Obj.prototype[Symbol.iterator] = function () {
const iterator = { next }
let current = this
function next() {
if (current) {
const value = current.value
current = current.next
return { done: false, value }
}
return { done: true }
}
return iterator
}
const one = new Obj(1)
const two = new Obj(2)
const three = new Obj(3)
one.next = two
two.next = three
for (const i of one)
console.log(i) // 1, 2, 3
function Obj(value) {
this.value = value
this.next = null
}
Obj.prototype[Symbol.iterator] = function () {
const iterator = { next }
let current = this
function next() {
if (current) {
const value = current.value
current = current.next
return { done: false, value }
}
return { done: true }
}
return iterator
}
const one = new Obj(1)
const two = new Obj(2)
const three = new Obj(3)
one.next = two
two.next = three
for (const i of one)
console.log(i) // 1, 2, 3
Array.from
将类似数组的对象(array-like object)和可遍历(iterable)的对象,转化为真正的数组
常见的类数组对象有: arguments、NodeList
js
// 类数组对象
const arrayLike = {
0: 'a',
1: 'b',
2: 'c',
length: 3
}
// ES5 的写法
const arr1 = [].slice.call(arrayLike) // ['a', 'b', 'c']
// ES6 的写法
const arr2 = Array.from(arrayLike) // ['a', 'b', 'c']
// 类数组对象
const arrayLike = {
0: 'a',
1: 'b',
2: 'c',
length: 3
}
// ES5 的写法
const arr1 = [].slice.call(arrayLike) // ['a', 'b', 'c']
// ES6 的写法
const arr2 = Array.from(arrayLike) // ['a', 'b', 'c']
generator
- generator 是一个函数生成器,被调用时会返回一个遍历器(迭代器 Iterator)对象,遍历器在执行过程中可以暂停和恢复
- Generator生成的函数调用时,不会立即执行,通过调用 next() 开始一步一步继续往下执行
- 第一次调用 next() 才开始执行,一直到第一个yield后面的执行完毕就暂停,第一个next() 无法传参
- next() 被调用,会停在 yield 处,返回右侧,左侧不执行,并且返还对象为
{ value: xx, done: boolean }
- 个人理解 Generator 函数是一个状态机,封装了多个内部状态
js
function* numberGenerator() {
const a = yield 1
console.log('🚀 ~ file: generator.md:25 ~ function*numberGenerator ~ a:', a)
yield 2
yield 3
}
const generator = numberGenerator('xxxxxxxxxx')
console.log(generator.next()) // 输出: {value: 1, done: false}
console.log(generator.next('params 2'))
// 🚀 ~ file: generator.md:25 ~ function*numberGenerator ~ a: params 2
// 输出: {value: 2, done: false}
console.log(generator.next()) // 输出: {value: 3, done: false}
console.log(generator.next()) // 输出: {value: undefined, done: true}
function* numberGenerator() {
const a = yield 1
console.log('🚀 ~ file: generator.md:25 ~ function*numberGenerator ~ a:', a)
yield 2
yield 3
}
const generator = numberGenerator('xxxxxxxxxx')
console.log(generator.next()) // 输出: {value: 1, done: false}
console.log(generator.next('params 2'))
// 🚀 ~ file: generator.md:25 ~ function*numberGenerator ~ a: params 2
// 输出: {value: 2, done: false}
console.log(generator.next()) // 输出: {value: 3, done: false}
console.log(generator.next()) // 输出: {value: undefined, done: true}