美文网首页
ES6(迭代器Iterator和for...of循环)

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

作者: KATENGC | 来源:发表于2020-05-06 10:13 被阅读0次
    一、什么是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循环)

          本文链接:https://www.haomeiwen.com/subject/nmunwhtx.html