初读阮一峰老师的这本书,简直如发现了新世界一般.原来ES6的语法是如此的清奇.
随着ES6, ES7, 到今年七月份的ES8. 我们会发现,javascript这门最初被定义在客户端的’玩具语言’已经变得越发的强壮和标准,这也是我们作为前端ers 所希望看到的,毕竟,这涉及到以后的饭碗呢哈哈.
阮一峰老师的文笔还是不错的,但是随着后面的阅读,会发现有一些后面的知识,被直接不明就里的拿到前面来用了,这就导致我这个新手小白就有点懵逼了.
比如说: 箭头函数,当然,这个比较好理解,有固定的语法
但是,阮老师一直有提到的iterator接口,到底是个啥? 估计初学ES6的新手小白自然会有着和我一样的困惑.
那么,下面就综合我的搜索和总结,对iterator接口的相关知识,做一个分享,也算是对自己所学的一个总结
iterator接口是什么
不知大家碰到此问题的时候是不是和我一样马上选择了百度(毕竟英语不够好,不能随随便便Google一下啊),泪奔~
百度上面会告诉你, Java的iterator很好用巴拉巴拉
那么,在javascript中,iterator接口到底是个神马东西呢?
iterator, 其实就是一个迭代器,或者说,是一个迭代器
在es6中,能表示“集合”概念的数据类型大致有四种:Array,Object,Map,Set
既然是集合,那遍历便是一种基本需求。而Iterator就是为了提供一种统一的接口机制。任何的数据结构,只要部署了Iterator接口,便可以使用类似的方式完成遍历操作。
当然,Iterator还有2个作用,它使数据结构的成员按某种次序排列,其次,es6有一种新的遍历方式,前面也说过,for…of,而Iterator的主要作用,就是支持此操作。
Iteartor的遍历过程是这样的
创建一个指向数据结构起始位置的指针。(起始位置不是第一个成员的位置,起始位置使一个单独的标志位。)
当调用next()方法,指针就向后移动一个位置,并返回当前位置上的成员,直到指针指向数据结构的结束位置为止。
第二步中,js语言返回的的成员信息是两个,value和done,value不用介绍,done是一个表示遍历是否结束的布尔值。
部署接口
上面我们说到的部署接口,那js怎么部署接口呢。其实我们之前已经说到过,在Symbol一节中,介绍了很多es6内置的Symbol值,这些就是接口。
es6中有三类结构生来就具有Iterator接口:数组、类数组对象、Map和Set结构。
当然,如果你和我一样,现在看到第八章的话,暂时是没有学到Map和Set结构的,这个看下就好
1 | var arr = [1,2,3,4]; |
数组,Map等结构中的成员都是有顺序的,即都是线性的结构,而对象,各成员并没有一个确定的顺序,所以遍历时先遍历谁后遍历谁并不确定。所以,给一个对象部署iterator接口,其实就是对该对象做一种线性转换。
如果有需要,可以手动给对象部署iterator接口
1 | let obj = { |
可以看到,Symbol.iterator会返回一个对象,这就是一个遍历器对象,而作为遍历器对象,其必须具备的特征就是必须具备next()方法。
至于可以使用Array.from转换成数组的类数组对象,部署iterator有一种很简单的方法,即直接使用数组的[Symbol.iterator]接口。
1 | fakeArray.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; |
用Generator函数来实现Symbol.iterator接口,事半功倍。
这也是看到第八章我要出来百度的原因,因为影响到了我正常的往下阅读了
1 | var yieldIterator = {}; |
注意,yield* 后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。
其次,其它调用到遍历器的操作还有解构赋值、扩展操作符、其它任何接受数组作为参数的场合,如:
for…of
Array.from()
Map(), Set(), WeakMap(), WeakSet()(比如)
Promise.all()
Promise.race()
一旦当你给你的结构部署了iterator接口,那么恭喜你,你可以使用for…of来遍历你的结构了!
遍历器对象除了必须布置next方法以外,还有2个可选方法。return()和throw()。当一个解构在遍历的时候异常提前退出(比如break,continue或者出错)的时候,就会调用return方法,其次,return方法必须返回一个对象。
至于throw方法,则是用于抛出错误,Generator.prototype.throw
for of循环有很多优点,比如不像for…in一样只遍历键名(甚至包括原型链上的键),而且不像foreach不能跳出循环。并且for…of为各种数据结构提供了一个统一的遍历方法。所以,尽量使用它吧~