细读MDN-Array

207 阅读3分钟

细读一下MDN,记录一些平常可能忽略的地方或是一些方法的特殊用处。

every

这个方法是用于测试数组中的所有元素是否能通过某个函数的测试。但是需要注意的是,如果接收的数组为空,无论什么情况该方法都会返回空。

const isBelowThreshold = (currentValue) => currentValue > 40;

const array1 = [1, 30, 39, 29, 10, 13];
console.log(array1.every(isBelowThreshold)); // result: false

const array2 = []
console.log(array2.every(isBelowThreshold)); // result: true

MDN中对这种情况的解释是:

无条件正确:正因为一个空集合没有元素,所以它其中的所有元素都符合给定的条件

fill

使用fill的时候,如果用的是对象去填充数组,实际上填充数组的会是这个数组的引用。比如想要用fill去创建一个二维数组并完成初始化,向下面这样写是行不通的:

const _2DArray = new Array(3).fill(new Array(3).fill(0))

console.log(_2DArray) // Array [Array [0, 0, 0], Array [0, 0, 0], Array [0, 0, 0]]

_2DArray[0][0] = 1

console.log(_2DArray)  // Array [Array [1, 0, 0], Array [1, 0, 0], Array [1, 0, 0]]

如果想快速的创建一个二维数组并且完成初始化的话,可以通过Array.prototype.from,下文会提到。

flatMap

flatMap就像是它的名字一样,本质上相当于是flat+map,也就是将数组通过map进行映射之后,再对得到的结果做一次深度为1的压缩。

const arr1 = [1, 2, 3, 4]
arr1.map(x => [x * 2]) // [[2], [4], [6], [8]]
arr1.flatMap(x => [x * 2]) // [2, 4, 6, 8]

在上面的例子中,flatMap能够完全被map所替代,无法体现flatMap的特别之处。但是flatMap有一个特殊的能力,不同于map的一一对应,经过它处理得到的数组长度可以和原本的不同。

// 我们约定:去除数组中的0,将浮点数的小数部分和整数部分拆开来
const array = [0, 1, 2, 13.4, 45.6, 3, 0]
const result = array.flatMap(item => 
  item === 0 ?
  [] :
  String(item).split('.').map(i => Number(i))
)
console.log(result) // [1, 2, 13, 4, 45, 6, 3]

from

使用from方法可以快速的创建一个二维数组并初始化,并且数组元素之间是彼此独立的,不会出现上面直接用fill创建的情况。

// 创建一个3x3的二维数组(九宫格)
const _2dArray = Array.from({length: 3}, (_, i) => 
    Array.from({length: 3}, (_, j) => i * 3 + j + 1)
)
console.log(_2dArray) // Array [Array [1, 2, 3], Array [4, 5, 6], Array [7, 8, 9]]

lastIndexOf

lastIndexOf和indexOf两个方法的第二参数都是设置查找的开始位置(fromIndex),但是该参数的值为负数的时候,两个方法会有细微的差别。

const animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo'];

console.log(animals.lastIndexOf('Dodo', -5)); // -1
console.log(animals.indexOf('Dodo', -5)); // 0

对于两个方法来说,-5指的都是从倒数第五个开始查找。但是lastIndexOf接受的负数,如果绝对值大于数组的长度,方法会直接返回-1,不去查找。但是indexOf在这个情况下会去查询整个数组,结果等价于fromIndex取默认值0。

注:文中使用的例子大多源自MDN,或是基于里面的例子进行补充以说明问题。