概念
Iterator(迭代器)是ES6
新增的一种接口类型,用于为表示集合
(Array
,Object
,Map
,Set
,NodeList
,arguments
)概念的数据结构提供统一的访问遍历机制。因此其作用主要包含三个方面: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);}
结果如下:
迭代器协议
迭代器是一种一次性使用的对象,用于迭代与其关联的可迭代对象即是集合类型的数据结构。迭代器每次调用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
结果如下:
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());
自定义迭代器
任何部署了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');
}
};
}
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!