JavaScript基础:迭代器

概念

Iterator(迭代器)是ES6新增的一种接口类型,用于为表示集合ArrayObjectMapSetNodeListarguments)概念的数据结构提供统一的访问遍历机制。因此其作用主要包含三个方面:1、为集合概念的数据结构提供统一访问机制;2、按照某种次序对数据结构的成员进行排列;3、为ES6提供的for...of遍历机制消费。简言之,其是一种有序的、连续的、基于拉取的用于消耗数据的组织方式,即是一个结构化的数据模式,用于从源以一次一个的方式提取数据。

interface Iterable {
  [Symbol.iterator] (): Iterator
}

interface Iterator {
  next (value?: any): IterationResult
  return ()?: IterationResult
  throw ()?: IterationResult
}

interface IterationResult {
  value: any
  done: boolean
}

// 为 Object 接入 Iterator
const iteratorObject = {
  name: 'Iterator',
  target: 'ES6',
  keyIndex: 0,
  [Symbol.iterator] () {
  	return this;
  },
  next () {
  	const keys = Object.keys(this);
    const len = keys.length;
    return {
      value: this[keys[this.keyIndex]],
      done: this.keyIndex++ >= len
    };
  }
};

执行for (const itValue of iteratorObject) {console.log(itValue);}结果如下:

itValue的值

迭代器协议

迭代器是一种一次性使用的对象,用于迭代与其关联的可迭代对象即是集合类型的数据结构。迭代器每次调用next API就会返回一个IterationResult对象,其中value表示迭代对象的值,done表示迭代是否耗尽。其中迭代器并不会与可迭代对象的某个时刻的快照绑定,而是通过指针记录可迭代对象的历程。也就是说,如果迭代对象在迭代期间发生了改变,这种改变同样的也会反应在迭代的过程中。

const itArray = ['ES6', 'ES8', 'ES9'];
const it = itArray[Symbol.iterator]();

console.log(it.next());

itArray.splice(1, 0, 'ES7');
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

log结果如下:

log的结果
ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性上。其中原生具备 Iterator接口的数据结构如下:

具有默认遍历的数据结构

const itMap = new Map([
  ['name', 'Iterator'],
  ['target', 'ES6'],
  ['module', 'Web']
]);

const it = itMap[Symbol.iterator]();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

itMap的log

自定义迭代器

任何部署了Iterator接口的对象都可以作为迭代器使用。

class ItClass {
  constructor (limit) {
  	this.limit = limit;
  }
  
  [Symbol.iterator] () {
    let count = 0;
  	return {
      next () {
      	return {value: count, done: count++ >= this.limit};
      }
    };
  }
}

如上类部署了Iterator接口,其实例化的对象就是可迭代对象。我们知道对象并没有部署Iterator接口,因其不是一个线性可遍历的结构,无法确定其属性的前后秩序,因此为Object部署Iterator接口也就是为其实现一套线性转换函数。

迭代器的异常处理

迭代器接口中return(...)throw(...)是可选接口,多数迭代器是没有实现这些可选接口。其中,return(...)用于通知在迭代器提前关闭时执行的逻辑,比如清理工作等。throw(...)用于向迭代器报告一个异常/错误,迭代器针对该信号做出对应的处理,通常是进行异常处理。一般,迭代器在return(...)throw(...)之后不会再产生任何值。

class itThrowClass {
  constructor (limit) {
  	this.limit = limit;
  }
  
  [Symbol.iterator] () {
    let count = 0;
  	return {
      next () {
      	return {value: count, done: count++ >= this.limit};
      },
      return () {
      	return {done: true};
      },
      throw () {
      	throw new Error('it error');
      }
    };
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值