# for...in 和 for...of

for..infor...of 都是用来遍历目标的。

# for...in

for..in 可以遍历数组 和 对象。对象主要是指 json,非常不建议用它来遍历 Map 和 Set,结果不可预测。

# 并不适合数组

  1. for...in 在遍历目标对象时,它获取到的是 索引值,而不是 value 值。

    对于数组来说,索引值是每一项的 index 值;对于 json 来说,索引是每一项的 key 值。

  2. 枚举属性顺序不确定

    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
    }
    
  3. 性能问题

    相比 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。

  1. for...of 循环直接返回迭代对象中的值。

  2. 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