迭代器、for...in 和 for...of

如果一个对象实现了 Symbol.iterator 属性,则被认为是一个可迭代的对象。一些内建对象如 ArrayMapString 等都有自己的 Symbol.iterator 属性实现。对象上 Symbol.iterator 的方法负责返回用来迭代的值列表。

for...of 语句

for...of 循环访问一个可迭代对象,并调用对象上的 Symbol.iterator 属性。

1
2
3
4
5
let someArray = [1, 'string', false];

for (let entry of someArray) {
console.log(entry); // 1, 'string', false
}

for...offor...in

for...offor...in 都能遍历列表,但是它们遍历的值是不同的:for...in 返回被遍历对象上所有键的列表,而 for...of 则返回被遍历对象上数字属性键的值列表。

1
2
3
4
5
6
7
8
9
let list = [4, 5, 6];

for (let i in list) {
console.log(i); // 0, 1, 2
}

for (let i of list) {
console.log(i); // 4, 5, 6
}

另一点不同的是,for...in 被用作检查对象属性的一种方法;而 for...of 则主要关注可迭代对象的属性值

1
2
3
4
5
6
7
8
9
10
11
12
let aSet = new Set(['Cat', 'Dog', 'Tiger']);
console.log(aSet); // Set(3) { 'Cat', 'Dog', 'Tiger' }
aSet['species'] = 'mammals';
console.log(aSet); // Set(3) { 'Cat', 'Dog', 'Tiger', spespecies: 'mammals' }

for (let i in aSet) {
console.log(i); // species
}

for (let i of aSet) {
console.log(i); // Cat, Dog, Tiger
}

如果对象是不可迭代的,则会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function iterateOverByForOf(target: any) {
for (let i of target) {
console.log(i);
}
}

function iterateOverByForIn(target: any) {
for (let i in target) {
console.log(i);
}
}

const aObj = {
1: 'One',
'A': 2
};

iterateOverByForIn(aObj); // 1, 'A'
iterateOverByForOf(aObj); // target is not iterable