Iterator 和 for...of 循环

本系列属于阮一峰老师所著的ECMAScript 6 入门学习笔记


Iterator(遍历器)

JavaScript表示“集合”的数据结构,除了ArrayObject ,ES6又新增了MapSet

遍历器(Iterator)是一种统一的接口机制,用来处理所有不同的数据结构。

Iterator的作用有三个:一位各种数据结构提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按照某种次序排列;三是ES6创造了一种新的命令for..of循环,Iterator接口主要供for...of消费

默认Iterator接口

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

可遍历的数据结构具有Symbol.iterator属性。执行这个属性会返回一个遍历器对象。该对象的根本特征就是具有next方法,每次调用next方法都会返回一个代表当前队员的信息对象,具有valuedone两个属性。

原生具备Iterator接口的数据类型如下:

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的arguments对象
  • NodeList对象
// 原生部署Itertor接口的数据接口,不用自己写遍历器生成函数,可使用for...of
lelt 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方法,但是无法中途跳出循环,不能使用breakreturn

for...in循环有几个缺点:

  • 数组的键名是数字,但是for...in循环是以字符串作为键名'0'、'2'、'3'等
  • for...in不仅遍历数字键名,还会遍历Iterator 和 for...of 循环手动添加的其他键,甚至包括原型链上的键
  • 某些情况下,for...in循环会以任意顺序遍历键名

与以上遍历相比,for...of有一些显著的优点

  • for...in一样简洁,但是没有那些缺点
  • 不同于forEach方法,可以和breakcontinuereturn配合使用
  • 提供了遍历所有数据结构统一的操作接口
posted @ 2017-10-19 16:11  coderAngus  阅读(133)  评论(0)    收藏  举报