定义可迭代对象
- 可迭代对象具有
Symbol.iterator
方法,调用这个方法会返回这个对象的迭代器。可以通过判断一个对象的Symbol.iterator
是否为一个方法,来判断这个对象是否为可迭代对象。
let values = [1,2,3]
let iterator = values[Symbol.iterator]()
- 数组、Set集合、Map集合、字符串都是可迭代对象,它们都有默认的迭代器。
- 通过生成器创建的迭代器都是可迭代对象,因为生成器默认会为
Symbol.iterator
属性赋值。
对比四种遍历方法
- for: 最基础的遍历方法,但写起来会比较复杂。
- for-in:适用于遍历普通对象,用于枚举对象的属性。
- forEach:不可以与break、continue和return配合使用,不可以在使用中改变原数组。
- for-of:用于遍历可迭代对象,首先通过调用数组的
Symbol.iterator
方法获取迭代器,循环每执行一次,都会调用可迭代对象的next()
方法。
创建可迭代对象
默认情况下,直接创建的对象都不是可迭代对象,但可以通过设置 Symbol.iterator
为一个生成器,将这个对象变为可迭代对象。
let collection = {
items:[],
*[Symbol.iterator](){
for (let item of this.items){
yield item;
}
}
};
collection.items.push(1);
collection.items.push(2);
collection.items.push(3);
for(let x of collection){
console.log(x); // 1,2,3
}
内建迭代器
集合迭代器
数组、Set集合、Map集合都内置了三种迭代器:
- entries() 返回一个迭代器,值为集合中所有键值对
- values() 返回一个迭代器,值为集合中所有键值
- keys() 返回一个迭代器,值为集合中所有键名
数组、Set集合的默认迭代器是 values(),Map集合的默认迭代器是 entries()。
let colors = ['red','green','blue']
// 这里使用 colors.values() 和直接写 colors 是一样的,因为数组的默认迭代器是 values()
for (let color of colors.values()){
console.log(color)
}
字符串迭代器
使用 for 循环遍历字符串的时候获取的是字符,所以对于双字节字符是没法正确返回的。但是在 for-of 中进行了改正,可以正确访问双字节字符。
NodeList迭代器
虽然是类数组,但是es6也为它添加了迭代器。
展开运算符可以操作所有可迭代对象,它就是根据默认迭代器进行返回的。