Skip to content

使用 for...in 遍历数组元素

for...in 其实是对象的遍历方式,并不是数组专有,使用 for...in 将循环遍历对象本身的所有可枚举属性,以及对象从其构造函数原型中继承的属性,其遍历顺序与 Object.keys()函数取到的列表一致。

该方法会遍历数组中非数字下标的元素,会忽略空元素:

js
let list = [7, 5, 2, 3];
list[10] = 1;
list["a"] = 1;
console.log(JSON.stringify(Object.keys(list)));

for (let key in list) {
  console.log(key, list[key]);
}
let list = [7, 5, 2, 3];
list[10] = 1;
list["a"] = 1;
console.log(JSON.stringify(Object.keys(list)));

for (let key in list) {
  console.log(key, list[key]);
}

输出:

["0","1","2","3","10","a"] 0, 7 1, 5 2, 2 3, 3 10, 1 a, 1

这个方法遍历数组是最坑的,它通常表现为有序,但是因为它是按照对象的枚举顺序来遍历的,也就是规范没有规定顺序的,所以具体实现是由着浏览器来的。MDN 文档里也明确建议“不要依赖其遍历顺序”:

for...of

这个方法用于可迭代对象的迭代,用来遍历数组是有序的,并且迭代的是数组的值。该方法不会遍历非数字下标的元素,同时不会忽略数组的空元素:

js
let list = [7, 5, 2, 3];
list[5] = 4;
list[4] = 5;
list[10] = 1;
// 此时下标6、7、8、9为空元素
list["a"] = "a";

for (let value of list) {
  console.log(value);
}
let list = [7, 5, 2, 3];
list[5] = 4;
list[4] = 5;
list[10] = 1;
// 此时下标6、7、8、9为空元素
list["a"] = "a";

for (let value of list) {
  console.log(value);
}

输出:

7 5 2 3 5 4 // 遍历空元素  // 遍历空元素  // 遍历空元素  // 遍历空元素 1

使用 for 循环

该方法和方法 2 比较像,是有序的,不会忽略空元素。

js
let list = ["a", "b", "c", "d"];
list[4] = "e";
list[10] = "z";
list["a"] = 0;

for (let idx = 0; idx < list.length; idx++) {
  console.log(idx, list[idx]);
}
let list = ["a", "b", "c", "d"];
list[4] = "e";
list[10] = "z";
list["a"] = 0;

for (let idx = 0; idx < list.length; idx++) {
  console.log(idx, list[idx]);
}

输出:

0, a 1, b 2, c 3, d 4, e 5, //空元素 6, 7, 8, 9, 10, z

forEach 遍历

forEach 是数组的一个高阶函数,用法如下:

arr.forEach(callback[, thisArg])

参数说明:

callback 为数组中每个元素执行的函数,该函数接收三个参数:

currentValue 数组中正在处理的当前元素。

index (可选) 数组中正在处理的当前元素的索引。

array (可选) forEach() 方法正在操作的数组。

thisArg (可选) 可选参数。当执行回调函数时用作 this 的值(参考对象)。

forEach 遍历数组会按照数组下标升序遍历,并且会忽略空元素:

js
let list = ["a", "b", "c", "d"];
list[4] = "e";
list[10] = "z";
list["a"] = 0;

list.forEach((value, key, list) => {
  console.log(key, value);
});
let list = ["a", "b", "c", "d"];
list[4] = "e";
list[10] = "z";
list["a"] = 0;

list.forEach((value, key, list) => {
  console.log(key, value);
});

输出:

0, a 1, b 2, c 3, d 4, e 10, z

有一个很容易忽略的细节,我们都应该尽可能地避免在遍历中取增删数组的元素,否则会出现一些意外的情况,并且不同的遍历方法还会有不同的表现。

倒叙遍历数组元素

js
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
for (var i = arr.length - 1; i >= 0; i--) {
  console.log(arr[i]);
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
for (var i = arr.length - 1; i >= 0; i--) {
  console.log(arr[i]);
}