迭代协议
其实就是一个迭代逻辑,完全可定制,规定了迭代什么,返回什么,如何迭代等等信息
迭代对象
表示可被迭代的对象,具体来说就是实现了 [Symbol.iterator] 方法的对象
// 一般可以在一个数组的原型中找到 [Symbol.iterator] 方法
使用
// 数组本身是实现了迭代器的(拥有 [Symbol.iterator] 方法)
let arr = [1, 2, 3, 4];
for (let val of arr) {
console.log(val);
}
给对象加上一个 [Symbol.iterator] 方法
让普通对象也成为迭代对象
let obj = {
x: 1,
y: 2,
z: 3,
};
// 给对象添加新的属性(给对象加上迭代器)
obj[Symbol.iterator] = function () {
// 当然在这里我们完全可以自己定义对象的迭代顺序
let keys = Object.keys(obj);
let index = 0;
return {
next() {
// 定义何时迭代结束
if (index >= keys.length) {
return {
done: true,
};
} else {
return {
// done 定义迭代是否完成
done: false,
// 循环的值(当然是可定制的)
value: {
key: keys[index],
value: obj[keys[index++]],
},
};
}
},
};
};
// 可迭代对象可以使用 for...of
// 调用 for...of 会去调用 Symbol.iterator 方法
for (let val of obj) {
console.log(val);
}
Generator
基于迭代器实现的一个可迭代函数, 其实也是 async + await 的前身(其实只要在 yield 后面跟一个 promise 就大体实现了 async + await)。
// Generator 函数
function* fn() {
// yield 用于定义每次返回的值
yield 1;
yield 2;
yield 3;
}
// 并不会立即执行
let res = fn();
//需要明确调用 next 方法才会执行
console.log(res.next()); // {value: 1, done: false}
console.log(res.next()); // {value: 2, done: false}
console.log(res.next()); // {value: 3, done: false}
console.log(res.next()); // {value: undefined, done: true}