聊一下JavaScript ES6的Iterator

389 阅读3分钟

这篇文章只是聊一下iterator的基础知识, 如果想全面了解iterator是什么东西, 可以点这

阮一峰老师的ES6入门

一 . Iterator是什么?

Iterator是一个提供给各种数据结构访问的统一接口, 简单来说, iterator就是一个接口

二 . Iterator有什么用?

使用iterator主要有三个作用

  • 为一些数据结构 Map,Set,Array,String... 提供一个统一的简便的访问接口
  • 使数据结构的成员按顺序排序,可以通过 next 关键字按顺序访问数据结构的数据
  • for...of 遍历消费 (主要)

三 . Iterator怎么用? (重点来了)

重点在这 : 所有的遍历器 iterator 都是从名为 [Symbol.iterator] 的接口(方法)开始出发的, 然后调用 next 方法按顺序输出数据


上面说到了 [Symbol.iterator] next , 那什么是 [Symbol.iterator]? 什么是 next?

  1. 什么是 [Symbol.iterator]
  • [Symbol.iterator]是启动遍历器的开关, 如果没有这个开关, 就不存在遍历器
  • [Symbol.iterator]分为先天的和后天的

首先, 先天的[Symbol.iterator]存在在一些特殊的数据结构中, 包括 Array String Map Set TypedArray arguments NodeList(dom) GeneratorObject等等, 如下图所示

看到没, 就是这个东西, 在我说的那几个数据结构中都有, 不信的可以自己一个一个去试试

但是, 不知道有没有发现, 我们最常用的 Object 是没有 [Symbol.iterator]接口的

所以 Object 是不能使用 for...of 进行遍历的

虽然 Object 有很多方法可以遍历, 但是产品经理就要你用 for ... of 遍历 Object , 怎么办, 这就要说到后天的 [Symbol.iterator]

var obj = {
    [Symbol.iterator] : () => {
        return {}
    }
}
for (const val of obj) {
    console.log(val)
}

Object 不是没有 [Symbol.iterator] 方法吗, 我们自己加一个不就行了

看 ! 现在 obj 是可遍历的了 ( 这里的错误先不管, 后面会说到 )


  1. 什么是 next

上面说过 iterator[Symbol.iterator] 开始, 通过 next 按顺序输出数据, 所以, 我们来看一下从 [Symbol.iterator] 出发后的是什么东西

可以很清楚的看到, [Symbol.iterator] 执行后会返回一个包含 next 方法的对象

所以 , next 就是由 [Symbol.iterator] 执行后返回的一个方法, 下面我们来执行一下next

每次执行 next 都会返回一个对象 {value: xxx, done: xxx}

value为遍历的数据结构的每一位, done 表示是否完成遍历

现在我们可以完善一下上面的错误了

var obj = {
    [Symbol.iterator] : () => {
        return {
            next : () => {
                const isContinue = (Math.random() > 0.75)
                if (isContinue) 
                    return { 
                        value : `数字 ${Math.floor(Math.random() * 10)}`, 
                        done : false 
                    }
                return { value : undefined, done : true}
            }
        }
    }
}
for (const val of obj) {
    console.log(val)
}

ber ~ 这样对象就算没有 [Symbol.iterator] 接口也可以使用 for ... of 去遍历了


  1. 什么是 for ... of

一直在用 for ... of, 顺带提一嘴, for ... of是什么玩意

for ... ofES6的一个新遍历的方法, 且只能遍历具有 iterator 接口的数据结构, 也就是要有 [Symbol.iterator], 至于这个遍历有什么好处, 大家可自行百度一下

四 . 总结

所有的遍历器 iterator 都是从名为 [Symbol.iterator] 的接口(方法)开始出发的, 然后调用 next 方法按顺序输出数据

ber~