JavaScript迭代协议解读
迭代协议分为可迭代协议和迭代器协议。
协议指约定俗成的一系列规则。
可迭代协议
可迭代协议规定了怎么样算是一个可迭代对象:可迭代对象或其原型链上必须有一个键为[Symbol.iterator]的属性。
一些内置类型如Array和Map均是可迭代对象,而Object不是。
let a = new Map();
let b = Object();
console.log(Symbol.iterator in a);//true
console.log(Symbol.iterator in b);//false
Symbol.iterator是一个无参函数,查看可迭代对象的原型链([[Prototype]])可知,它指向了entris(),调用它将返回一个符合迭代器协议的迭代器对象。
console.log(a[Symbol.iterator]);//[Function:entries]
完成迭代
a.set(1,1).set(2,2).set(3,3);
console.log(a.entries());//[Map Entries] { [ 1, 1 ], [ 2, 2 ], [ 3, 3 ] }
console.log(...a);//[ 1, 1 ] [ 2, 2 ] [ 3, 3 ]
迭代器协议
迭代器是按需创建的一次性接口对象,每个迭代器都会关联一个可迭代对象。
迭代器协议规定:实现了Iterabor接口的同时定义了一个next()方法的对象为一个迭代器。
迭代器具有三个方法:next()、return()和throw()。后两个是可选的。
- next():无参数或者接受一个参数,并返回一个符合
IteraborResult
接口的对象。
IteraborResult有两个属性:- done:为true时,迭代终结;为false时,迭代继续。
- value:value作为返回值返回,done为true时忽略。
- return(value):无参数或者接受一个参数,执行必要的清理工作(例如关闭数据库连接),并返回一个符合
IteraborResult
接口的对象,通常返回的value等于传进来的arguments.value,而done为true。 - throw():无参数或者接受一个参数的函数,并返回符合
IteratorResult
接口的对象。
接下来,手动使用类实现一个迭代器:
class myIterator{
constructor(limit){
this.limit=limit;
}
[Symbol.iterator](){
let count=1,limit=this.limit;
return{
next(){
if(count<=limit){
return {done:false,value:count++};
}
else{
return {done:true,value:undefined};
}
}
}
}
}
let my_iterator=new myIterator(3);
for(let i of my_iterator) console.log(i);
/**
* 1
* 2
* 3
*/
或者用生成器实现迭代器:
const myIterator = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
},
};
console.log([...myIterator]);
function * idMaker(){
let id = 0;
while (true) {
yield id++;
}
}
const it = idMaker();
console.log(it.next().value);//0