我在总结 Array 中的方法的时候,发现带有遍历效果的函数中有许多共同之处,因此写一篇总结。

此文没有将 reduce 方法加进来,因为它的参数和其它的方法不一样。

方法列表

  • Array.prototype.every()

测试数组的所有元素是否能通过回调函数的测试,返回一个布尔值

  • Array.prototype.some()

测试数组的元素是否至少有一个能够通过回调函数的测试,返回一个布尔值

  • Array.prototype.forEach()

遍历数组,返回undefined

  • Array.prototype.map()

遍历数组,返回一个数组

  • Array.prototype.filter()

过滤数组,返回一个过滤后的数组

  • Array.prototype.find()

查找数组中符合条件的第一个元素,返回这个元素的值

  • Array.prototype.findIndex()

查找数组中符合条件的第一个元素,返回这个元素的下标

每个方法详细的使用方法可以查阅 MDN——Array (opens new window)

共同之处

参数

callback :在数组每一项上执行的函数,接收 3 个参数:

  • item
    当前遍历到的元素。
  • index可选
    当前遍历到的索引。
  • array可选
    数组本身。

thisArg 可选:

  • 执行回调时用作this 的对象。

原数组不改变

也就是调用这个方法的数组,本身是不会被这个方法所改变的。不会像 sort 那样,改变原来的数组。

但是,你是可以通过 callback 来修改原来的数组的。

  1. let arr = [1, 2, 3];
  2. let noEffect = arr.forEach((item, index) => {
  3. // forEach 本身不会修改原数组, 但是里面的回调可能会修改原数组
  4. arr[index] = item * 2;
  5. // 没有效果的
  6. return item;
  7. })
  8. console.log(noEffect); // undefined
  9. console.log(arr); // (3) [2, 4, 6]

遍历的范围是确定的

当数组调用该方法,该方法开始执行的时候,遍历的长度就已经确定了,如果在遍历的过程中,添加了元素,那么这个元素将不会被遍历到。

  1. let arr = [1, 2, 3];
  2. arr.forEach((item, index) => {
  3. if(index === 1){
  4. // 无法遍历到4
  5. arr.push(4);
  6. }
  7. console.log(item);
  8. })

虽然遍历的范围是确定的范围是确定的,但是遍历的值不是确定的。

如果我们在方法遍历到某一个元素之前,修改了这个元素的值,那么遍历的结果将会以修改后的值为准。

  1. let arr = [1, 2, 3, 4];
  2. arr.forEach((item, index) => {
  3. if( index === 1 ) {
  4. // 删除arr的第三个值, 让他的索引值为空,因此不会打印出3,因为值改变了,我们把他的索引删掉了
  5. delete arr[2];
  6. // 上面是删除索引值,这里的例子是修改元素的值
  7. arr[3] = 999;
  8. }
  9. console.log(item); // 1 2 999
  10. })
  11. console.log(arr); // (4) [1, 2, empty, 999]

异同之处

大部分地方其实是相同的,因此我用一个表格来描述,会更加的清晰

方法名称 返回值 稀疏 / 空索引 注意点
every() Boolean 跳过 收到空数组,一定返回 true
some() Boolean 跳过 收到空数组,一定返回 false
forEach() undefined 跳过 遍历无法 return,没有返回值
map() Array 跳过 会跳过空索引,但是结果会出现空索引
filter() Array 跳过
find() Number 不跳过 若没找到返回 undefined,空索引值为 undefined
findIndex() Number 不跳过 若没找到返回 -1,空索引值为 undefined

关于稀疏数组

稀疏数组也就是索引值为空的数组

关于 map

  1. let arr = [1, 2, , 4];
  2. let result = arr.map((item) => {
  3. // 很明显,empty的时候回调函数里面的代码是没有执行的
  4. console.log('current item', item);
  5. return item*2;
  6. })
  7. console.log(result); // (4) [2, 4, empty, 8]

image.png

关于 find/findeIndex

  1. let arr = [1, 2, , 4];
  2. let result = [];
  3. arr.find((item) => {
  4. // 即使索引值为空,也会访问到,并且值为undefined
  5. result.push(item);
  6. })
  7. console.log(result); // (4) [1, 2, undefined, 4]