1.可迭代对象与 for-of 循环
2.内置的迭代器
3.字符串的迭代器
可迭代对象与 for-of 循环
可迭代对象( iterable )是包含 Symbol.iterator 属性的对象
ES6 中,所有的集合 对象(数组、 Set 与 Map )以及字符串都是可迭代对象
可迭代对象被设计用于与 ES 新增的 for-of 循环配合使用
生成器创建的所有迭代器都是可迭代对象,因为生成器默认就会为Symbol.iterator 属 性赋值
for-of 循环在循环每次执行时会调用可迭代对象的 next() 方法,并将结果对象的 value值存储在一个变量上。循环过程会持续到结果对象的 done 属性变成 true 为止。
let values = [1, 2, 3];
for (let num of values) {
console.log(num);
}
// 1 2 3
在不可迭代对象、 null 或undefined 上使用 for-of 语句,会抛出错误
可以使用 Symbol.iterator 来访问对象上的默认迭代器
let values = [1, 2, 3];
let iterator = values[Symbol.iterator]();
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next()); // {value: undefined, done: true}
Symbol.iterator指定了默认迭代器,可以使用它来检测一个对象是否能进行迭代.
function isIterable(object) {
return typeof object[Symbol.iterator] === "function";
}
console.log(isIterable([1, 2, 3])); // t
console.log(isIterable("Hello")); // t
console.log(isIterable(new Map())); // t
console.log(isIterable(new Set())); // t
console.log(isIterable(new WeakMap())); // f
console.log(isIterable(new WeakSet())); // f
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);
}
内置的迭代器
集合的迭代器
ES6 具有三种集合对象类型:数组、 Map 与 Set 。
entries() :返回一个包含键值对的迭代器;
values() :返回一个包含集合中的值的迭代器;
keys() :返回一个包含集合中的键的迭代器。
entries() 返回一个双项数组
let colors = [ "red", "green", "blue" ];
let tracking = new Set([1234, 5678, 9012]);
let data = new Map();
data.set("title", "Understanding ES6");
data.set("format", "ebook");
for (let entry of colors.entries()) {
console.log(entry); // [0, 'red'] ……
}
for (let entry of tracking.entries()) {
console.log(entry);
}
for (let entry of data.entries()) {
console.log(entry);
}
values() 迭返回集合中的每一个值
let colors = [ "red", "green", "blue" ];
let tracking = new Set([1234, 5678, 9012]);
let data = new Map();
data.set("title", "Understanding ES6");
data.set("format", "ebook");
for (let value of colors.values()) {
console.log(value); // red blue ……
}
for (let value of tracking.values()) {
console.log(value);
}
for (let value of data.values()) {
console.log(value);
}
keys() 返回集合中的每一个键
只返回了数值类型的键
Set的键与值是相同的,因此它的 keys() 与 values() 返回了相 同的迭代器;
对于Map , keys() 迭代器返回了每个不重复的键。
let colors = [ "red", "green", "blue" ];
let tracking = new Set([1234, 5678, 9012]);
let data = new Map();
data.set("title", "Understanding ES6");
data.set("format", "ebook");
for (let key of colors.keys()) {
console.log(key);
}
for (let key of tracking.keys()) {
console.log(key);
}
for (let key of data.keys()) {
console.log(key);
}
集合类型的默认迭代器
当 for-of 循环没有显式指定迭代器时,每种集合类型都有一个默认的迭代器供循环使用。
values() 方法是数组与 Set 的默认迭代器,
entries() 方法则是 Map 的默认迭代器。
let colors = [ "red", "green", "blue" ];
let tracking = new Set([1234, 5678, 9012]);
let data = new Map();
data.set("title", "Understanding ES6");
data.set("format", "print");
// 与使用 colors.values() 相同
for (let value of colors) {
console.log(value);
}
// 与使用 tracking.values() 相同
for (let num of tracking) {
console.log(num);
}
// 与使用 data.entries() 相同
for (let entry of data) {
console.log(entry);
}
字符串的迭代器
从 ES5发布开始, JS 的字符串就慢慢变得越来越像数组。(如:使用text[0] 来获取第一个字符,以此类推)
不过 方括号表示法工作在码元而非字符上,因此它不能被用于正确访问双字节的字符。
var message = "A B" ;
for (let i=0; i < message.length; i++) {
console.log(message[i]);
}
// A
//
// B
改为使用字符串默认迭代器配合 for-of 循环
var message = "A B" ;
for (let c of message) {
console.log(c);
}
// A
//
// b