ES6 —— Iterator 迭代器

一、Iterator(迭代器)的概念

含义:Iterator (迭代器)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历该数据结构所有成员的操作。

原生具备 Iterator 接口的数据结构如下:

  • Array
  • Map
  • Set
  • String
  • 函数的 Arguments 对象
  • DOM 的 Nodelist 对象
  • TypedArray

ES6规定:默认的 Iterator 接口部署在 Symbol.iterator 属性,Symbol.iterator 是内置的 Symbol 值,内置的 Symbol 值可以作为【对象】的属性,扩展对象的行为。Symbol.iterator 是一个表达式,必须放在中括号内;它本质是个函数,是当前数据结构默认的迭代器生成函数,执行该函数会返回一个迭代器。

示例:默认的 Iterator 接口

//声明一个数组
const arr = ['hello', 'world', 'nihao']
//执行数组的 Symbol.iterator方法,得到数组默认的 Iterator 接口
const iterator = arr[Symbol.iterator]() 

一种数据结构只要部署了 Iterator 接口,就称该数据结构是可遍历的(iterable)。

二、Iterator 的迭代过程

**

  1. 调用迭代器生成函数,返回一个指针对象(迭代器的本质),指向数据结构的起始位置
  2. 第一次调用迭代器的 next() 方法,指针指向数据结构的第一个成员(next() 方法是 Iterator 的默认方法),next() 方法的返回值是一个对象,包含当前数据结构成员的信息,有value和done两个属性,value对应该成员的值,done对应布尔值,如果遍历还在进行,值为false,如果遍历结束,值为true
  3. 不断调用 next() 方法,直到指针指向数据结构的结束位置

**
示例:数组的 Iterator 接口调用next方法(接上一个例子)

const arr = ['hello', 'world', 'nihao']

const iterator = arr[Symbol.iterator]() 

console.log(iterator.next())//{value: "hello", done: false}
console.log(iterator.next())//{value: "world", done: false}
console.log(iterator.next())//{value: "nihao", done: false}
console.log(iterator.next())//{value: undefined, done: true}

注意:遍历完所有成员后,继续调用next方法时,value的值为undefined

对象(Object)没有默认部署 Iterator 接口,就必须在 Symbol.iterator属性上部署迭代器生成方法。

示例:给 banji 部署 Iterator 接口,遍历 stus 数组中的成员

//声明一个对象
const banji = {
      name: "终极一班",
      stus: [
        'xiaoning',
        'xiaoming',
        'xiaotian',
        'knight'
      ],
      //部署迭代器生成方法
      [Symbol.iterator](){
        //保存外层this
        const _this = this
        //索引变量
        let index = 0
        return {
          next(){
            if(index < _this.stus.length){
              return {value: _this.stus[index++], done: false}
            }else{
              return {value: undefined, done: true}
            }
          }
        }
      }
    }
//测试
    const iterator = banji[Symbol.iterator]()

    console.log(iterator.next())//{value: "xiaoning", done: false}
    console.log(iterator.next())//{value: "xiaoming", done: false}
    console.log(iterator.next())//{value: "xiaotian", done: false}
    console.log(iterator.next())//{value: "knight", done: false}
    console.log(iterator.next())//{value: undefined, done: true}

三、for…of 循环

实际上,Iterator 接口主要供 for…of 循环消费,也就是指,使用 for…of 循环,会自动调用当前数据结构的 Symbol.iterator 属性方法。

示例:直接使用 for…of 遍历 banji(接上一个例子)

for (let v of banji){
      console.log(v)
    }
    /*
    xiaoning
    xiaoming
    xiaotian
    knight  
    */

其它默认调用 Iterator 的常见场合如下:

  • 解构赋值:对于数组和 Set 结构的解构赋值
  • 扩展运算符
  • yield *:后跟一个可遍历的数据结构时,会调用该结构的 Iterator 接口
  • 任何接收数组作为参数的场合,如:Array.from()

四、总结

Iterator 的主要作用具备如下:

  • 为各种数据结构提供统一、简便的访问接口
  • 使得数据结构的成员能够按照某种次序排列
  • ES6新的遍历命令 for…of 循环,Iterator 主要供 for…of 消费

转载出处:
ECMAScript 6 入门
作者:阮一峰
https://es6.ruanyifeng.com/#docs/iterator

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值