一、ECMAScript-迭代器-Iterator
1. Iterator接口
- Iterator是一种接口机制,为各种不同的数据结构提供统一访问的机制
- 主要供for…of 消费
- 让不支持遍历的数据结构 “可遍历”
function makeIterator(arr) {
let nextIndex = 0
return {
next() {
return nextIndex < arr.length ? {
value: arr[nextIndex++],
done: false
}: {
value: undefined,
done: true
}
}
}
}
let it = makeIterator(['a', 'b', 'c'])
console.log(it.next())
console.log(it.next())
console.log(it.next())
console.log(it.next())
let arr = ['a', 'b', 'c']
let it = arr[Symbol.iterator]()
console.log(it.next())
console.log(it.next())
console.log(it.next())
console.log(it.next())
let map = new Map()
map.set('name', 'es')
map.set('age', 5)
map.set('school', '清华')
let it = map[Symbol.iterator]()
console.log(it.next())
console.log(it.next())
console.log(it.next())
console.log(it.next())
2. 原生具备Iterator接口的数据结构
- Array
- Map
- Set
- String
- TypedArray
- 函数的arguments对象
- NodeList对象
3. 对不具备Iterator接口的数据结构,想实现可遍历
- 可迭代协议:Symbol.iterator
- 迭代器协议:return { next() {return {value, done}}}
let courses = {
allCourse: {
frontend: ['ES', '小程序', 'Vue', 'React'],
backend: ['Java', 'Python', 'SpringBoot'],
webapp: ['Android', 'iOS']
}
}
courses[Symbol.iterator] = function() {
let allCourse = this.allCourse
let keys = Reflect.ownKeys(allCourse)
let values = []
return {
next() {
if (!values.length) {
if(keys.length) {
values = allCourse[keys[0]]
keys.shift()
}
}
return {
done: !values.length,
value: values.shift()
}
}
}
}
for (let c of courses) {
console.log(c)
}
courses[Symbol.iterator] = function* () {
let allCourse = this.allCourse
let keys = Reflect.ownKeys(allCourse)
let values = []
while (1) {
if (!values.length) {
if(keys.length) {
values = allCourse[keys[0]]
keys.shift()
yield values.shift()
} else {
return false
}
} else {
yield values.shift()
}
}
}