任何数据结构只要部署了Iterator接口,就可以使用for…of 来遍历
具备iterator接口的数据类型
- Array
- Argunments
- Set
- Map
- String
- TypedArray
- NodeList 这个接口就是对象里面的一个属性,属性的名字叫Symbol.iterator,也可以自己对结构进行布置iterator接口
工作原理
-
先创建一个指针对象,指向当前数据结构的起始位置
-
第一次调用对象的next方法,指针自动指向数据结构的第一个成员
-
接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
-
每次调用next方法就会返回一个包含value和done属性(是否完成)的对象
-
上面给大家举例了很多可迭代对象,那它们必定是符合可迭代对象协议的,思考以下代码
const bears = ['ice', 'panda', 'grizzly']
//数组的Symbol.iterator方法
const iter = bears[Symbol.iterator]()
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
const nickName = 'ice'
//字符串的Symbol.iterator方法
const strIter = nickName[Symbol.iterator]()
console.log(strIter.next())
console.log(strIter.next())
console.log(strIter.next())
console.log(strIter.next())
可迭代对象的实现
let info = {
bears: ['ice', 'panda', 'grizzly'],
[Symbol.iterator]: function() {
let index = 0
let _iterator = {
//这里一定要箭头函数,或者手动保存上层作用域的this
next: () => {
if (index < this.bears.length) {
return { done: false, value: this.bears[index++] }
}
return { done: true, value: undefined }
}
}
return _iterator
}
}
let iter = info[Symbol.iterator]()
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
//符合可迭代对象协议 就可以利用 for of 遍历
for (let bear of info) {
console.log(bear)
}
//ice panda grizzly
- 符合可迭代对象协议,是一个对象,有
[Symbol.iterator]方法,并且这个方法返回了一个迭代器对象。 - 当我利用for of 遍历,就会自动的调用这个方法
- 当使用扩展运算符(...)或者对数组和 Set 结构进行解构赋值时,会默认调用Symbol.iterator方法
let arr1 = [1,3]
let arr2 = [2,3,4,5]
arr2 = [1,...arr2,6]
console.log(arr2) // [1, 2, 3, 4, 5, 6]
迭代器的封装实现
const bears = ['ice', 'panda', 'grizzly']
function createArrIterator(arr) {
let index = 0
let _iterator = {
next() {
if (index < arr.length) {
return { done: false, value: arr[index++] }
}
return { done: true, value: undefined }
}
}
return _iterator
}
let iter = createArrIterator(bears)
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
自定义类迭代实现
class myInfo {
constructor(name, age, friends) {
this.name = name
this.age = age
this.friends = friends
}
[Symbol.iterator]() {
let index = 0
// console.log(this);
let _iterator = {
next: () => {
const friends = this.friends
if (index < friends.length) {
return {done: false, value: friends[index++]}
}
return {done: true, value: undefined}
}
}
return _iterator
}
}
const info = new myInfo('ice', 22, ['panda','grizzly'])
for (let bear of info) {
console.log(bear)
}
//panda
//grizzly
- 此案例只是简单的对
friends进行了迭代,你也可以迭代你想要的一切东西...