ES6(迭代器Iterator和for...of循环)

一、什么是Iterator接口

Iterator是带有特殊接口的对象。含有一个 next()方法,调用返回一个包含两个属性的对象,分别是valuedonevalue表示当前位置的值,done表示是否迭代完,当为true的时候,调用next就无效了。

ES5中遍历通常用for循环,数组还有 forEach 方法,对象就是 for-in,ES6 中又添加了 MapSet ,而迭代器可以统一处理所有集合数据的方法。迭代器是一个接口,只要你这个数据结构暴露了一个iterator的接口,那就可以完成迭代。ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费。

数据结构只要部署了Iterator接口,我们就认为这种数据结构为“可遍历”(Iterable)。ES6 规定,默认的 Iterator 接口部署在数据结构的 Symbol.iterator属性,或者说,一个数据结构只要具有 Symbol.iterator数据,就可以认为是“可遍历的”(iterable)。

可以供 for...of 消费的原生数据结构

  • Array
  • Map
  • Set
  • String
  • TypedArray(一种通用的固定长度缓冲区类型,允许读取缓冲区中的二进制数据)函数中的 arguments 对象
  • NodeList 对象

可以发现上面的原生数据结构中没有对象Object

{
    let arr = ['hello', 'world'];
    let map = arr[Symbol.iterator]();
    console.log(map.next());// {value: "hello", done: false}
    console.log(map.next());// {value: "world", done: false}
    console.log(map.next());// {value: undefined, done: true}
}

这里直接调用数组的Symbol.iterator接口,这个接口其实是数组内部已经帮我们实现了,所以我们可以直接调用,返回的是一个mapmap有一个next方法

对象Object是没有Iterator接口的,无法通过for...of的方式遍历对象

{
    let obj = {
        start: [1, 3, 5],
        end: [2, 4, 6],
    };

    // Object 没有 Iterator接口
    // 会报错obj[Symbol.iterator] is not a function
    // for (let key of obj) {
    //     console.log(key);
    // }
}

那是否可以自定义一个Iterator接口呢?答案是可以的

{
    let obj = {
        start: [1, 3, 5],
        end: [2, 4, 6],
        [Symbol.iterator]() {
            let self = this;
            let index = 0;
            let arr = self.start.concat(self.end);
            let len = arr.length;

            return {
                next() {
                    if (index < len) {
                        return {
                            value: arr[index++],
                            done: false //是否结束 false还没有结束
                        }
                    } else {
                        return {
                            value: arr[index++],
                            done: true //是否结束 true已经结束
                        }
                    }
                }
            }
        }
    };

    for (let key of obj) {
        console.log(key)
    }

}

你可能感兴趣的:(ES6(迭代器Iterator和for...of循环))