ES6中的Iterator

Iterator

遍历器,是一种接口,为不同的数据结构提供一个统一的访问机制,任何数据结构只要部署了Iterator接口,就可以完成遍历操作。

ES6中创造了一种新的遍历命令for...of,而Iterator就是供for...of操作。

Iterator 的遍历过程:

  • 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
  • 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
  • 第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
  • 不断调用指针对象的next方法,直到它指向数据结构的结束位置。

调用next方法,会返回一个包含value和done这两个属性的对象。value为当前属性的值,done是一个Boolean值,表示遍历是否结束了。

一种数据结构只要部署了iterator结构,那么这种数据结构就是可遍历的iterable

在ES6中。默认Iterator接口部署在数据结构的symbol.iterator属性,该属性是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数就会返回一个遍历器。

const obj = {
  [Symbol.iterator] : function () {
    return {
      next: function () {
        return {
          value: 1,
          done: true
        };
      }
    };
  }
};

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

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

其他数据结构(主要是对象)的 Iterator 接口,都需要在Symbol.iterator属性上面部署,这样才会被for...of循环遍历。

对于类似数组的对象(存在数值键名和length属性),部署 Iterator 接口,有一个简便方法,就是Symbol.iterator方法直接引用数组的 Iterator 接口。

NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
// 或者
NodeList.prototype[Symbol.iterator] = [][Symbol.iterator];


另一个例子
let iterable = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3,
  [Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
  console.log(item); // 'a', 'b', 'c'
}

普通对象部署数组的`Symbol.iterator`方法不起作用
let iterable = {
  a: 'a',
  b: 'b',
  c: 'c',
  length: 3,
  [Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
  console.log(item); // undefined, undefined, undefined
}

如果Symbol.iterator方法对应的不是遍历器生成函数(即会返回一个遍历器对象),解释引擎将会报错。

var obj = {};
obj[Symbol.iterator] = () => 1;
[...obj] // TypeError: [] is not a function 扩展运算符也是采用了遍历器

有了遍历器接口,数据结构就可以用for...of循环遍历,也可以使用while循环遍历。

var $iterator = ITERABLE[Symbol.iterator]();
var $result = $iterator.next();
while (!$result.done) {
  var x = $result.value;
  // ...
  $result = $iterator.next();
}

使用了iterator接口的场合

  1. 解构赋值,对数组和 Set 结构进行解构赋值时,会默认调用Symbol.iterator方法。
  2. 扩展运算符,(…)也会调用默认的 Iterator 接口。
  3. for…of
  4. Map(),Set(),WeakMap(),WeakSet()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值