在整个ES过程中操作某些数据结构 比如说 Array、Object、Set、Map他们都可以理解是一个数据集合,对于数据集合我们怎么去进行读取是一个问题,因为本身数据结构不同,怎么才能用一种相同办法的一个接口让这些不同的数据结构得到一个统一的读取的这么一个方式,这就是Iterator接口所要实现的功能
for…of为什么不能遍历Object对象
1 | //定义一个的Object对象 |
- 要想能够被for…of正常遍历的,都需要实现一个遍历器Iterator。而数组,Set和Map结构,早就内置好了遍历器Iterator(又叫迭代器),它们的原型中都有一个Symbol.iterator方法;而Object对象并没有实现这个接口,使得它无法被for…of遍历
验证数据结构原型中到底是不是有个叫Symbol.iterator的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20//数组
Array.prototype[Symbol.iterator];
//结果:function values(){...}
//字符串
String.prototype[Symbol.iterator];
//结果:function [Symbol.iterator](){...}
//Set结构
Set.prototype[Symbol.iterator];
//结果:function values(){...}
//Map结构
Map.prototype[Symbol.iterator];
//结果:function entries(){...}
//Object对象
Object.prototype[Symbol.iterator];
//结果:undefined - Object对象没有Symbol.iterator是因为数据形式我们可以随意写 所以我们可以给Object加上Symbol.iterator方法
Iterator遍历器的原理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41var arr = ['hello','world']
let map = arr[Symbol.iterator]()
console.log(map.next())
console.log(map.next())
console.log(map.next())
//打印结果
//{value: "hello", done: false}
//{value: "world", done: false}
//{value: undefined, done: true}
```1
- for...of的原理就是:先调用可遍历对象的[Symbol.iterator]( )方法,得到一个iterator遍历器对象,然后就在遍历器上不断调用next( )方法,直到done的值为true的时候,就表示遍历完成结束了。
##### 给Object对象自定义Iterator遍历器使其支持for...of循环
```bash
let obj = {
start:[1,3,2],
end:[7,8,9],
[Symbol.iterator](){
let _this = this;//指向
let index = 0;//索引
let arr = _this.start.concat(_this.end)//合并数组
let len = arr.length
return {
next(){
if(index<len){
return {
value:arr[index++],//避免值不变化
done:false
}
}else{
return {
value:arr[index++],
done:true
}
}
}
}
}
}
for(let key of obj){
console.info(key)//1 3 2 7 8 9
} - Symbol.iterator方法,必须有next( )方法,next( )方法返回的对象包含了value属性和done属性。