上篇说到迭代可以按照一定的规则,从指定的空间中取出数据。区别于循环的是,迭代过程不知道数据的长度,也不知道要取多少个数据。迭代器(iterator)是一个具有next方法的对象,next方法返回下一个数据并且能指示是否迭代完成;迭代器创建函数是一个返回迭代器的函数。这一篇来讲一下可迭代协议和for-of循环。
1.可迭代协议
ES6规定,如果一个对象具有知名符号属性Symbol.iterator,并且属性值是一个迭代器创建函数,则该对象是可迭代的(iterable)
【注】判断一个对象是否可迭代,就是查看该对象中是否存在属性Symbol.iterator。上篇中我们对数组进行了迭代,现在打印一个数组,查看它的proto,如下
const arr = [1, 3, 4, 2];
console.log(arr)
【注】遍历可迭代对象的方法,上一篇我们用了while循环来判断是否进入迭代过程,es6提供了for-of循环来进行迭代,下面还是将while的例子拿过来再康康
const arr = [1, 3, 4, 2];
const iterator = arr[Symbol.iterator]();
let result = iterator.next();
while (!result.done) {
const item = result.value;
console.log(item);
result = iterator.next()
}
2.for-of循环
for-of循环用于遍历可迭代对象,for(const item of iterable) {},如下例,其打印结果同图1
const arr = [1, 3, 4, 2];
for (const iterator of arr) {
console.log(iterator)
}
3.展开运算符与可迭代对象
展开运算符可以作用于可迭代对象,这样就可以轻松的将可迭代对象转换为数组
const obj = {
a: 1,
b: 2,
[Symbol.iterator]() {
const keys = Object.keys(this);
console.log(keys);
let i = 0;
return {
next: () => {
const propName = keys[i];
const propValue = this[propName];
const result = {
value: {
propName,
propValue
},
done: i >= keys.length
}
i++;
return result;
}
}
}
}
const arr = [...obj];
console.log(arr);
function test(a, b) {
console.log(a, b)
}
test(...obj)