在 JavaScript 中有几种方法可以遍历数组,关于哪种方法是正确的方法存在很多争论。 一般来说,有4种常见的模式:

  1. 简单的 for 循环: for (let i = 0; i < arr.length; ++i)
  2. 函数方法如 forEach()arr.forEach((v, i) => { /* ... */ })
  3. for-of 循​​环: for (const v of arr)
  4. for-in 循环: for (const i in arr)

以下是 4 种常见方法之间的几个最重要的区别。

TLDR: 尽可能使用 for-of (3)。 简单的 for 循环(1)也可以。 不要 _ 使用 for/in

异步/等待 支持

具有功能方法的大问题,例如 forEach() 就是这样,因为您将一个单独的函数传递给 forEach()使用 async/await forEach() 很难 。例如,下面的代码将以相反的顺序打印数字 0-9,因为 forEach() 并行执行异步函数,并没有给你处理错误的方法。

async function print(n) {
  // Wait 1 second before printing 0, 0.9 seconds before printing 1, etc.
  await new Promise(resolve => setTimeout(() => resolve(), 1000 - n * 100));
  // Will usually print 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 but order is not strictly
  // guaranteed.
  console.log(n);
}

async function test() {
  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(print);
}

test();

另一方面,异步函数与 JavaScript 的内置循环配合得很好。

async function print(n) {
  await new Promise(resolve => setTimeout(() => resolve(), 1000 - n * 100));
  console.log(n);
}

async function test() {
  // Prints 0-9 in order.
  for (const num of [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) {
    await print(num);
  }
}

test();

非数字属性

JavaScript 数组是对象。 typeof [] === object,这意味着数组可以具有非数字属性。 避免使用的主要原因 for/in 就是它 for/in 迭代非数字属性,而 forforEach(), 和 for/of 跳过非数字属性。

const arr = [a, b, c];
arr[bad] = alpha;

for (let key in arr) {
  console.log(arr[key]); // Prints: a, b, c, alpha
}

// However, `for/of` skips non-numeric keys
for (const val of arr) {
  console.log(val); // Prints: a, b, c
}

// So does `forEach()`
arr.forEach(val => console.log(val)); // Prints: a, b, c

const 迭代器键

使用简单时的一个常见错误 for 循环无意中增加 i,我已经记不清有多少次我不小心在嵌套中增加了错误的计数器 for 循环。

for (let i = 0; i < arr.length; ++i) {
  // So easy to accidentally type `++i` below.
  for (let j = 0; j < arr.length; ++i) {

  }
}

forEach()for/offor/in 具有能够通过意外修改循环索引来防止弄乱循环的好处。你可以修改 index 参数,但这对循环没有影响。 for/offor/each,您可以将迭代器键标记为 const

for (const [i, el] of Object.entries(arr)) {
  ++i; // Compile time error
}

概括

下面是比较循环结构的图表:

图片[1]-如何在 JavaScript 中遍历数组-技术鸭(jishuya.cn)

你应该更喜欢使用 for/of 除非你有充分的理由不这样做。 您可能想使用 forEach() 对于一些整洁的语法糖 filter()map(),或者您可能实际上想要遍历数组上的非数字属性并使用 for/in,但 for/of 是最稳健的方法,几乎​​适用于所有情况。

© 版权声明
评论 抢沙发

请登录后发表评论