1. 概述
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
1)ES6创造了一种新的遍历命令for…of循环,Iterator 接口主要供 for…of消费
2)原生具备Iterator接口的数据(可用for of遍历)
- Array
- Arguments
- Set
- Map
- String
- TypedArray
- NodeList
3)工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
- 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
- 没调用next 方法返回一个包含 value 和 done 属性的对象
注意:需要自定义遍历数据的时候,要想到迭代器
2. 自定义遍历数据
<script>
const Person = {
name: 'xy',
active: [
'吃饭',
'睡觉',
'写代码'
]
}
</script>
定义一个对象如上,现在的需求:用for of 遍历active数组并依次输出其中的内容。
这里就需要用到迭代器自定义遍历。
首先我们先直接 for of 输出看下
<script>
const Person = {
name: 'xy',
active: [
'吃饭',
'睡觉',
'写代码'
]
}
for (let index of Person) {
console.log(index);
}
</script>
结果:
提示我们Person不是可迭代的,也就是缺少迭代器,不能for of遍历。
根据工作原理,我们加上迭代器,再输出
<script>
const Person = {
name: 'xy',
active: [
'吃饭',
'睡觉',
'写代码'
],
// 1.添加迭代器
[Symbol.iterator]() {
}
}
for (let index of Person) {
console.log(index);
}
</script>
结果:
提示我们迭代器方法返回的值不是一个对象,可我们值没有返回,需要添加return返回
<script>
const Person = {
name: 'xy',
active: [
'吃饭',
'睡觉',
'写代码'
],
// 1.添加迭代器
[Symbol.iterator]() {
// 2.添加返回值
return {
}
}
}
for (let index of Person) {
console.log(index);
}
</script>
又提示我们值不是一个方法,再看原理,需要返回一个next方法,加上
<script>
const Person = {
name: 'xy',
active: [
'吃饭',
'睡觉',
'写代码'
],
// 1.添加迭代器
[Symbol.iterator]() {
// 2.添加返回值
return {
// 3.添加next方法
next: function () {
}
}
}
}
for (let index of Person) {
console.log(index);
}
</script>
说结果又不是一个对象,再看原理,next方法里返回一个包含value、done的对象,假定一个:
<script>
const Person = {
name: 'xy',
active: [
'吃饭',
'睡觉',
'写代码'
],
// 1.添加迭代器
[Symbol.iterator]() {
// 2.添加返回值
return {
// 3.添加next方法
next: function () {
// 4.添加返回对象
return { value: 123, done: false }
}
}
}
}
for (let index of Person) {
console.log(index);
}
</script>
这时这个迭代器基本就可以用了,但是它处于一直输出,而且没达到我们要求,这时就需要按需所改了
<script>
const Person = {
name: 'xy',
active: [
'吃饭',
'睡觉',
'写代码'
],
// 1.添加迭代器
[Symbol.iterator]() {
let index = 0;
let that = this;
// 2.添加返回值
return {
// 3.添加next方法
next: function () {
// 4.添加返回对象
if (index < that.active.length) {
const result = { value: that.active[index], done: false };
index++;
return result;
}
else {
return { value: undefined, done: true };
}
}
}
}
}
for (let index of Person) {
console.log(index);
}
</script>
这里添加了索引 index 来对应遍历的下标 ,让 that=this,来引用外层this指向。
通过index大小进行条件判断,如果没有遍历完,则返回当前下标的值value与未完成遍历done:false,否则返回value:undefined,done:true。