# Iteratorfor...of循环

表示集合的数据结构有Array/Object/Map/Set。遍历器为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作。

TIP

Iterator作用有三个:

  • 为各种数据结构提供一个统一的,简便的访问接口;
  • 使得数据结构成员能够按某种次序排列;
  • ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费。

Iterator遍历过程如下:

  1. 创建一个指针对象,指向当前数据结构的起始位置。遍历器对象本质上是一个指针对象。
  2. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
  3. 第二次调用指针对象的next方法,指向数据结构第二个成员。
  4. 不断调用next方法,直到数据结构的结束位置。

每次调用next方法都会返回数据结构的当前成员的信息。具体来说就是一个包含valuedone两个属性的对象。done表示遍历是否结束。**对于遍历器对象来说,done:falsevalue:undefined属性是可以省略的。

当用for...of循环遍历某种数据结构时,该循环会自动去寻找Iterator接口。

# 默认Iterator接口

ES6规定默认的Iterator接口部署在数据结构的Symbol.iterator属性,一个数据结构具有该属性就是可遍历的。

const obj = {
    [Symbol.iterator]: function() {
        return {
            next:function() {
                return {
                    value: 1,
                    done: true
                }
            }
        }
    }
}

const text = {
    a: 1,
    b: 2,
    c: 3
}
for(let item of text) {
    console.log(item)
}
// 没有加入遍历器接口会报错: text is not iterable

// 解决办法
text[Symbol.iterator] = function() {
    const _this = this
    return {
        index: -1,
        next() {
            console.log(this)
            console.log(_this)
            let arr = Object.keys(_this)
            if(this.index < arr.length) {
                this.index++
                return {
                    value: _this[arr[this.index]],
                    done: false
                }
            } else {
                return {
                    value: undefined,
                    done: true
                }
            }
        }
    }
}
for(let item of text) {
    console.log(item) // 1 2 3 undefin
}
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
44
45
46
47
48
49
50