本系列属于阮一峰老师所著的学习笔记
Iterator(遍历器)
JavaScript表示“集合”的数据结构,除了Array
、Object
,ES6又新增了Map
和Set
。
遍历器(Iterator)是一种统一的接口机制,用来处理所有不同的数据结构。
Iterator的作用有三个:一位各种数据结构提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按照某种次序排列;三是ES6创造了一种新的命令for..of
循环,Iterator接口主要供for...of
消费
默认Iterator接口
ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator
属性,一个数据结构只要具有Symbol.iterator
属性,就可以认为是“可遍历的”(iterable)。
可遍历的数据结构具有Symbol.iterator
属性。执行这个属性会返回一个遍历器对象。该对象的根本特征就是具有next
方法,每次调用next
方法都会返回一个代表当前队员的信息对象,具有value
和done
两个属性。
原生具备Iterator接口的数据类型如下:
- Array
- Map
- Set
- String
- TypedArray
- 函数的arguments对象
- NodeList对象
// 原生部署Itertor接口的数据接口,不用自己写遍历器生成函数,可使用for...oflelt arr = [1,2,3]let iter = arr[Symbol.iterator]()iter.next() // {value:1,done:false}iter.next() // {value:2,done:false}iter.next() // {value:3,done:false}iter.next() // {value:undefined,done:false}// 类似对象不具备Itertor接口,需要自己部署Symbol.iterator属性let obj = { data: ['hello','world'], [Symbol.iterator](){ const self = this let index = 0 return { next(){ if(index < self.data.length){ return { value: self.data[index++], done: false } }else{ return {value: undefined,done:true} } } } }}// 类数组对象(存在数值键名和length属性),Symbol.iterator方法可直接引用数组的Iterator接口NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]
遍历器对象的return(),throw()
遍历器对象除了具有next
方法,还具有return
方法和throw
方法
return
方法的使用场合是:如果for...of
循环提前退出(通常是因为出错,或者有break
语句或continue
语句,就会调用return
方法。如果一个对象在完成遍历前需要清理或释放资源,就可以部署return
方法)
throw
方法主要是配合Generator函数使用,一般遍历器对象用不到这个方法
for...of循环
ES6 借鉴 C++、Java、C# 和 Python 语言,引入了for...of
循环,作为遍历所有数据结构的统一的方法。
JavaScript提供多种遍历语法,最原始的for
循环,比较麻烦。
数组提供内置的forEach
方法,但是无法中途跳出循环,不能使用break
或return
for...in
循环有几个缺点:
- 数组的键名是数字,但是
for...in
循环是以字符串作为键名'0'、'2'、'3'等 for...in
不仅遍历数字键名,还会遍历Iterator 和 for...of 循环手动添加的其他键,甚至包括原型链上的键- 某些情况下,
for...in
循环会以任意顺序遍历键名
与以上遍历相比,for...of
有一些显著的优点
- 和
for...in
一样简洁,但是没有那些缺点 - 不同于
forEach
方法,可以和break
、continue
和return
配合使用 - 提供了遍历所有数据结构统一的操作接口