迭代器是被设计专用于迭代的对象,带有特定接口。所有的迭代器对象都拥有 next() 方法,会返回一个结果对象。该结果对象有两个属性:对应下一个值的 value ,以及一个布尔类型的 done ,其值为 true 时表示没有更多值可供使用。
ES5中创建一个迭代器
function createIterator(items) {
var i = 0;
return {
next: function() {
var done = (i >= items.length);
var value = !done ? items[i++] : undefined;
return {
done: done,
value: value
};
}
};
}
var iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); // "{done: false, value: 1}"
console.log(iterator.next()); // "{done: false, value: 2}"
console.log(iterator.next()); // "{done: false, value: 3}"
console.log(iterator.next()); // "{done: true, value: undefined}"
ES6提供的生成器,让创建迭代器对象变得更简单。
生成器是能返回一个迭代器的函数。
生成器函数由放在function关键字之后的一个星号(*)来表示,并能使用新的yield关键字。
yield指定了迭代器在被next() 方法调用时应当按顺序返回的值。
function *createIterator(items) {
for (let i = 0; i < items.length; i++) {
yield items[i];
}
}
//创建生成器也可以使用生成器函数表达式,上面第一行代码改成
//let createIterator = function *(items) {
var iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); // "{value: 1, done: false}"
console.log(iterator.next()); // "{value: 2, done: false}"
console.log(iterator.next()); // "{value: 3, done: false}"
console.log(iterator.next()); // "{value: undefined, done: true}"
生成器就是函数,可以被添加到对象中。
var o = {
//ES5中使用函数表达式创建生成器,如果是ES6中第一行可以简化成*createIterator(items) {
createIterator: function *(items) {
for (let i = 0; i < items.length; i++) {
yield items[i];
}
}
};
let iterator = o.createIterator([1, 2, 3]);
可迭代对象与 for-of 循环
可迭代对象是包含 Symbol.iterator 属性的对象。
ES6 中,所有的集合对象(数组、Set与Map)以及字符串都是可迭代对象,因此它们都被指定了默认的迭代器。
可迭代对象被设计用于与 ES 新增的 for-of 循环配合使用。
for-of 循环在循环每次执行时会调用可迭代对象的 next() 方法,并将结果对象的 value
值存储在一个变量上。循环过程会持续到结果对象的 done 属性变成 true 为止。
let values = [1, 2, 3];
for (let num of values) {
console.log(num);
}
使用Symbol.iterator访问对象的默认迭代器
let values = [1, 2, 3];
let iterator = values[Symbol.iterator]();
console.log(iterator.next()); // "{value: 1, done: false}"
console.log(iterator.next()); // "{value: 2, done: false}"
console.log(iterator.next()); // "{value: 3, done: false}"
console.log(iterator.next()); // "{value: undefined, done: true}"
集合的迭代器
集合的3种对象类型:数组、Map与Set都拥有如下的迭代器:
entries() :返回一个包含键值对的迭代器;
values() :返回一个包含集合中的值的迭代器;
keys() :返回一个包含集合中的键的迭代器。
当 for-of 循环没有显式指定迭代器时,每种集合类型都有一个默认的迭代器供循环使用。
values() 方法是数组与 Set 的默认迭代器,而 entries() 方法则是 Map 的默认迭代器。
let colors = [ "red", "green", "blue" ];
for (let entry of colors.entries()) {
console.log(entry);
}
/*输出:
[0, "red"]
[1, "green"]
[2, "blue"]
*/
for (let entry of colors.values()) {
console.log(entry);
}
/*输出:
"red"
"green"
"blue"
*/
for (let key of colors.keys()) {
console.log(key);
}
/*输出:
0
1
2
*/
for (let entry of colors) {
console.log(entry);
}
/*输出:
"red"
"green"
"blue"
*/
解构与 for-of 循环
Map 默认迭代器的行为有助于在 for-of 循环中使用解构。
let data = new Map();
data.set("title", "Understanding ES6");
data.set("format", "ebook");
// 与使用 data.entries() 相同
for (let [key, value] of data) {
console.log(key + "=" + value);
}