研究数组迭代方法:稀疏数组处理、多种遍历方式

image

数组迭代方法的研究

我们知道数组存在一些迭代方法将会遍历数组,在这篇文章中主要研究一些这些方法的相关问题,比如说稀疏数组处理方法、如何打断、方法内异常处理等等。

稀疏数组处理方法

不同的迭代方法在处理稀疏数组的时候存在不同的方式,在 MDN 中指出,在旧的迭代方法中处理空槽的方式与处理包含 undefined索引的方式不同,而在新的迭代方法中不会对空槽进行特殊处理,而是将它们视为包含 undefined​。

在旧的方法中对空槽的方式是 “诸如 forEach之类的迭代方法根本不会访问空槽。其他方法,如 concatcopyWithin等,在进行复制时会保留空槽,因此最终数组依然是稀疏的。”

以下数组对数组进行了特殊处理 concat()​、copyWithin()​、every()​、filter()​、flat()​、flatMap()​、forEach()​、indexOf()​、lastIndexOf()​、map()​、reduce()​、reduceRight()​、reverse()​、slice()​、some()​、sort()​ 和 splice()​。

不对空槽进行特殊处理的方法,将其视为 undifined ​的方法有:entries()​、fill()​、find()​、findIndex()​、findLast()​、findLastIndex()​、includes()​、join()​、keys()​、toLocaleString()​、values()​ 和 with()​。

引用

  1. MDN - 数组方法和空槽

数组迭代方法的打断方式

如果需要在数组迭代时需要灵活的中断迭代,通常建议使用传统的 for循环或 for...of循环,这样可以更直接地使用 break来中断循环。

当然我们也可以研究一些常见方法的打断方式,比如说,我们在方法外设置一个变量 isBreak ​作为判断是否是否需要打断的依据,在需要打断的地方将 isBreak 设置为 true,当然我们需要在方法的前面放一段特殊的代码。整体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let isBreak;

let arr = [1, 2, 3, 4, 5];
arr.forEach((item, idnex) => {
   if(idnex === 0){
       isBreak = false;
  }
   if(isBreak){
       return;
  }
   console.log(item);
   if(item === 3) {
       isBreak = true;
  }
})

在这个例子中,isBreak​ 用于控制循环是否继续。当遇到 item === 3​ 时,我们将 isBreak​ 设置为 true​,从而在下次迭代时跳过后续的逻辑。

当然也有一些方法自带打断,例如:

  1. some 会在存在一个元素符合测试函数时,停止遍历,并且返回 true;
  2. every 会在存在一个元素不符合测试函数是,停止遍历,并且返回 false;
  3. find 和 findIndex 会在找到第一个符合的元素时,停止遍历,并且返回值或者索引;

数组迭代方法的异常处理

在数组迭代方法的异常处理中通常需要思考的问题主要是,出现异常是否继续执行接下来的迭代,如果需要执行接下来的迭代通常是将 try-catch 防止方法内,如果出现了异常将不需要迭代剩下的元素,就需要将 try-catch 放在方法外。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let arr = [1, 2, 3, 4, 5];
arr.forEach(item => {
   try {
       if (item === 3) {
           throw new Error('Something went wrong!');
      }
       console.log(item);
  } catch (error) {
       console.error(`Error processing item ${item}: ${error.message}`);
  }
});

// 输出:
// 1
// 2
// Error processing item 3: Something went wrong!
// 4
// 5

在上面的代码中,假设在 item===3 的时候出现了一个不是很严重的问题,后续代码可以继续执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let arr = [1, 2, 3, 4, 5];
try {
   arr.forEach(item => {
       if (item === 3) {
           throw new Error('Something went wrong!');
      }
       console.log(item);
  });
} catch (error) {
   console.error(`Iteration stopped due to error: ${error.message}`);
}

// 输出:
// 1
// 2
// Iteration stopped due to error: Something went wrong