【深入学习JS】10_迭代器(Iterator)

概念

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

作用:

  • 为各种数据结构,提供一个统一的、简便的访问接口;
  • 使得数据结构的成员能够按某种次序排列;
  • for...of依靠的就是Iterator实现的。

基本使用

function makeIterator(arr){
    let nextIndex = 0;
    return {
        next: function(){
            return nextIndex < arr.length?
                { value: arr[nextIndex++], done: false }:
                { value: undefined, done: true};
        }
    }
}

let it = makeIterator(['a', 'b', 'c']);
it.next(); // {value: "a", done: false}
it.next(); // {value: "b", done: false}
it.next(); // {value: undefined, done: true}

定义一个函数,返回一个next方法,这个方法返回包含了valuedone的对象,其中done代表循环是否到了头。

常见的可迭代的数据结构

Array、Map、Set、String、TypeArray、arguments和NodeList都具备Iterator接口,所以可以使用for...of循环它们。

以数组为例:

const arr = [1, 2];
console.log(arr);     // 在arr.__proto__中存在Symbol.iterator

let it = arr[Symbol.iterator]();
console.log(it.next()); // {value: 1, done: false}
console.log(it.next()); // {value: 2, done: false}
console.log(it.next()); // {value: undefined, done: true}

for(let i of arr){
    console.log(arr); 
}

// 1
// 2

默认调用了Iterator的场景:

  • 解构赋值;
  • 扩展运算符;
  • yield*
  • for...of
  • Array.from()
  • Map(), Set(), WeakMap(), WeakSet()
  • Promise.all()
  • Promise.race()

实际应用

假定有这么一个对象:

let obj = {
    'All': '不限',
    0: '按男生搜索',
    1: '按女生搜索'
}

由于对象不能使用for.. of循环,我们使用for..in循环:

 for(let key in obj){
     console.log(key);
 }
// 打印的顺序是 0 1 All

这时候有一个需要求,是需要先显示All,再显示其他选项, 所以可以给obj新增iterator,使得数据结构的成员能够按某种顺序排列:

// 获得当前的对象的所有key,并按一定顺序存入数组中,每次next时就返回数组对应的key 
function makeIterator(){
      const self = this;
      let keys = Object.keys(this);
      let arr = [];
      keys.forEach(key => {
        if(key === 'All'){
          arr.unshift(key);
        }else {
          arr.push(key);
        }
      });
      let len = arr.length;
      let nextIndex = 0;
      return {
        next(){
          return nextIndex < len?
                { value: arr[nextIndex++], done: false }:
                { value: undefined, done: true};
        }
      }
    }

let obj = {
    0: '按男生搜索',
    1: '按女生搜索',
    'All': '不限',
    [Symbol.iterator]: makeIterator
}


for(let k of obj){
  console.log(k);        // All 0 1
}

这样即为对象提供了for...of方法,也能按照自己想要的迭代顺序迭代了。

参考

Iterator 和 for…of 循环


若有错误,欢迎指出,感谢~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值