es6的学习笔记(四):iterators and iterable
iterator本质上是一种协议,用于定义适用于所有对象的迭代
迭代规则
所有的对象,都可以使用迭代协议,只要为它添加一个属性名为[Symbol.iterator],属性值为遵循协议的一个函数就可以使用迭代协议。
var s={
name:[1,2,3,4,5],
value:0,
[Symbol.iterator]:function(){ //绑定一个方法,该方法返回一个具有next方法的对象。
return {
next:()=>{
if(this.value==this.name.length){
this.value = 0; //此处需要将控制迭代的数值清零,不然只能迭代一次,亲测
return {value:undefined,done:true};
}
else {
return {value:this.name[this.value++],done:false};
}
}
}
}
}
for(let value of s){
console.log(value);//输出1,2,3,4,5
}
当为对象s绑定了属性名为[Symbol.iterator],且属性值符合一定的要求,就可以使用for of来进行迭代。在该方法中,应该符合以下几个规则:
- 返回值是next函数
- next函数没有参数,返回值是一个对象{value,done}
- done表示该序列是否迭代结束,是一个boolean类型
- value是当前的输出值
注意迭代器结束时需将控制迭代的数字还原,不然迭代器只能使用一次,其实也不算使用一次,它可以继续使用,只是使用一次之后如果不归零,再次使用直接就结束,也就没有任何数值输出,容易出错而已
这样,就可以使用for of 语句迭代,数值就是next方法中的value,而结束就是根据done的值来判断是否结束。
自带迭代属性的对象
上述的方法使得普通的对象也可以进行迭代,不过,还有一些预定义的对象也具有迭代性。比如:Array,String,DOM中的NodeList,arguments都是默认可以迭代的,也就是可以直接使用for of结构。
将可迭代的对象还原为数组
有两种方法,一种是spread操作符。一种是Array.form函数。Array.from除了可以把可迭代对象转换成数组,也可以把类数组对象转换成数组。类数组对象就是属性名为0,1,2,3,4并且具有length属性的对象
var s={
name:[1,2,3,4,5],
value:0,
[Symbol.iterator]:function(){ //绑定一个方法,该方法返回一个具有next方法的对象。
return {
next:()=>{
if(this.value==this.name.length){
this.value = 0;
return {value:undefined,done:true};
}
else {
return {value:this.name[this.value++],done:false};
}
}
}
}
}
console.log(...s);//此处直接使用...操作符,输出1 2 3 4 5,此处是没有,的,因为并没有转换成数组,相当于连续输出了
console.log(Array.from(s));//此处输出1,2,3,4,5
var q = [...s];//使用...操作符将s转换成数组
console.log(q);//输出1,2,3,4,5
for(let i in q)
console.log(i)//输出0-4
console.log(Array.from({0:'a',1:'b',2:'c',length:3}));//此处输出a,b,c
无限序列
如果在next函数中,done变量始终是false,那么这个序列永远不会结束,同样的,如果对这个序列进行Array.from()或者[…]操作以及for of都会使程序崩溃。
const x = {
[Symbol.iterator]:()=>{
return {
next:()=>{return {value:Math.random(),done:false}}
}
}
}
console.log(x[Symbol.iterator]().next().value)//不断执行,一直会产生一个新的随机数
for(let s of x)
console.log(s)//后面的for循环一旦执行,浏览器的控制台就卡住,只能关闭重启
const [one, another] = random //可以使用这样的结构来访问有限的无限序列中的元素
console.log(one)
// <‐ 0.23235511826351285
console.log(another)
// <‐ 0.28749457537196577