迭代器
JavaScript 原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了Map和Set。这样就需要一种统一的接口机制,来处理所有不同的数据结构。遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员) 。
Iterator的作用
- 为各种数据结构,提供一个统一的、简便的访问接口;
- 使得数据结构的成员能够按某种次序排列
- ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of使用,也就是说prototype需要有[Symbol.iterator]。
原生具备iterator接口的数据(可用for of遍历)
- Array
- set容器
- map容器
- String
- 函数的 arguments 对象
注意普通对象不能用迭代器 // 会报Uncaught TypeError: obj is not iterable
当普通对象没有迭代器怎么办?
当普通对象没有 Symbol.iterator属性时
- 从别的地方借过来使用。
- 或者我们可以给他造一个
function myIterator(arr) {
let nextIndex = 0
return {
next: function() {
return nextIndex < arr.length
? { value: arr[nextIndex++], done: false }
: { value: undefined, done: true }
}
}
}
let arr = [1, 4, 'ads']// 准备一个数据
let iteratorObj = myIterator(arr)
console.log(iteratorObj.next()) // 所有的迭代器对象都拥有next()方法,会返回一个结果对象
console.log(iteratorObj.next())
console.log(iteratorObj.next())
console.log(iteratorObj.next())
其实可以让对象都变成可迭代对象, 只需要他们拥有 Symbol.iterator 属性即可
使用for of循环去验证一下即可
// 思路1:借助用这个对象的 Symbol.iterator
let obj = {
0: 200,
1: 300,
2: 400,
length: 3,
}
obj[Symbol.iterator] = Array.prototype[Symbol.iterator]
for (let val of obj) {
console.log(val)
}
let obj = { a: 1 }
Object.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]
for (const key of obj) {
console.log(key)
}
// 思路2 自己再去实现一个迭代器规范
Object.prototype[Symbol.iterator] = function() {
let that = this, // 当前对象
i = 0,
keys = Reflect.ownKeys(that)
// Object.keys(self).concat(Object.getOwnPropertySymbols(self))
return {
next() {
console.log(i >= keys.length, keys.length, i, 'i >= length')
if (i >= keys.length) {
return {
value: undefined,
done: true
}
} else {
return {
value: [keys[i++]],
done: false
}
}
}
}
}
let obj = {
name: 'juice',
age: 24
}
for (let value of obj) {
console.log(value)
}
各位看官如遇上不理解的地方,或者我文章有不足、错误的地方,欢迎在评论区指出,感谢阅读。