# for...in 和 for...of
for..in
和 for...of
都是用来遍历目标的。
# for...in
for..in
可以遍历数组 和 对象。对象主要是指 json,非常不建议用它来遍历 Map 和 Set,结果不可预测。
# 并不适合数组
for...in
在遍历目标对象时,它获取到的是 索引值,而不是 value 值。对于数组来说,索引值是每一项的 index 值;对于 json 来说,索引是每一项的 key 值。
枚举属性顺序不确定
for...in
循环不仅遍历数组自身的可枚举属性,还遍历其原型链上的可枚举属性。因此,如果你修改了 Array.prototype 或者有其他代码修改了它,for...in 可能会返回一些意料之外的属性键。
const arr = ["a", "b", "c", "d", "e"]; Array.prototype.aBird = "aBird"; for (let i in arr) { console.log(i); // 0, 1, 2, 3, 4, aBird }
性能问题
相比 for 循环或 for...of 循环,for...in 循环在处理数组时可能更慢,因为它需要检查数组的每个属性是否存在于原型链上。
# 遍历数组的索引
const arr = ["apple", "banana", "cherry"];
for (let index in arr) {
console.log(index); // 输出:0, 1, 2
console.log(arr[index]); // 输出:'apple', 'banana', 'cherry'
}
# 遍历对象的属性
当 for...in
遍历对象的可枚举属性时,不包括原型链上的属性。
const obj = {
a: 1,
b: 2,
c: 3,
};
for (let key in obj) {
console.log(key); // 输出:a, b, c
console.log(obj[key]); // 输出:1, 2, 3
}
# for...of
for...of
是 ES6 中引入的一个新的循环结构,主要用于遍历 可迭代(iterable)的对象。包括 Array, Map, Set, String, TypeArray, 函数的 arguments 等。
注意,for...of
不能遍历对象的属性,默认的 json 并不是可迭代的类型,所以无法遍历 json。
for...of
循环直接返回迭代对象中的值。for...of
循环体内部可以使用 break、continue 和 return 来控制循环流程。
# 遍历数组
const array = [1, 2, 3, 4, 5];
for (let value of array) {
console.log(value); // 输出:1, 2, 3, 4, 5
}
# 遍历字符串
const str = "hello";
for (let char of str) {
console.log(char); // 输出:h, e, l, l, o
}
# 遍历 Map
const map = new Map();
map.set("key1", "value1");
map.set("key2", "value2");
for (let [key, value] of map) {
console.log(key, value); // 输出:key1 value1, key2 value2
}
# 遍历 Set
const set = new Set([1, 2, 3, 2, 1]);
for (let value of set) {
// 输出:1, 2, 3(Set 中的元素是唯一的,所以重复的元素只会被输出一次)
console.log(value);
}
# 遍历 TypeArray
const typedArray = new Uint8Array([10, 20, 30, 40, 50]);
for (let value of typedArray) {
console.log(value); // 输出:10, 20, 30, 40, 50
}
# 遍历函数的 arguments 对象
function exampleFunction() {
for (let arg of arguments) {
console.log(arg);
}
}
exampleFunction(1, 2, 3); // 输出:1, 2, 3