12.迭代器

 

迭代器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。

1.ES6 创造了一种新的遍历命令 for…of 循环, Iterator 接口主要供 for…of

2.原生具备 iterator 接口的数据类型(可用 for of 遍历)

  • Array
  • Arguments
  • Set
  • Map
  • String
  • TypedArray
  • NodeList
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const fruit = ['apple', 'banana', 'grapes', 'orange'];
/* for of 和 for in的区别*/
// key-value中的value
for(let e of fruit) {
console.log(e);
/**
* apple
* banana
* grapes
* orange
*/
}
// key-value中的key
for(let i in fruit) {
console.log(fruit[i]);
/**
* apple
* banana
* grapes
* orange
*/
}

3.工作原理

  • 创建一个指针对象,指向当前数据结构的起始位置
  • 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
  • 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
  • 每调用 next 方法返回一个包含 value 和 done 属性的对象
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
41
42
43
const fruit = ['apple', 'banana', 'grapes', 'orange'];

console.log(fruit);
// Symbol(Symbol.iterator): ƒ values()
// Symbol.iterator属性是一个方法,使用()调用
let iterator = fruit[Symbol.iterator]();
console.log(iterator);
/**
* Array Iterator {}
* [[Prototype]]: Array Iterator
* next: ƒ next()
* Symbol(Symbol.toStringTag): "Array Iterator"
* [[Prototype]]: Object
*/
// 有next()属性方法

console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
/*
{
"value": "apple",
"done": false
},
...
,
{
"value": "orange",
"done": false
},
{
"value": undefined,
"done": true
},
{
"value": undefined,
"done": true
}
value = undefined是因为遍历到头了,done = true表示遍历完成了
*/

自定义遍历对象

1
2
3
4
5
6
7
8
9
const fruit_market = {
name: "fruit_market",
commodity: ['apple', 'banana', 'grapes', 'orange']
};

for(let f of fruit_market) {
console.log(f);
}
// Uncaught TypeError: fruit_market is not iterable
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
const fruit_market = {
name: "fruit_market",
commodity: ['apple', 'banana', 'grapes', 'orange'],
[Symbol.iterator]() {
let index = 0;
return {
next: () => {
if (index < this.commodity.length) {
const result = {
value: this.commodity[index],
done: false
};
index++;
return result;
} else {
const result = {
value: undefined,
done: true
};
return result;
}
}
};
}
};

for(let f of fruit_market) {
console.log(f);
/**
* apple
* banana
* grapes
* orange
*/
}