前言

数组是 JavaScript 中最常用的数据结构之一,它允许我们存储和操作一组数据。在 JavaScript 中,数组是一种特殊的对象,它具有一些内置的方法,可以帮助我们更方便地操作数组。本文从创建到操作,整理了大部分常用方法(部分冷门和基本用不到的就省略了,需要时自行 CDN 吧,不用真会忘 ……)

创建数组的方式

Array 数组构造函数

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Array

用于创建一个新数组,接收一个或者多个参数

1
2
3
4
5
new Array() // []
new Array(4) // [,,,,] 长度为4的数组,但是数组元素并不存在
new Array('4') // ['4'] 长度为1, 数组元素是字符串4
new Array(2, 3) // [2, 3] 长度为参数长度,所有参数作为数组元素构建数组
new Array(undefined) // [undefined] 长度为1, 元素是 undefined

from 从可迭代或类数组创建浅拷贝

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/from

静态方法,从可迭代或类数组对象创建一个新的浅拷贝的数组实例。

1
2
3
4
5
console.log(Array.from('foo'))
// Expected output: Array ["f", "o", "o"]

console.log(Array.from([1, 2, 3], x => x + x))
// Expected output: Array [2, 4, 6]

fromAsync

这是一个异步版本的 Array.from 同样是从可迭代对象或者类数组创建一个新数组。不过这里迭代可以是 Promise,并使用的是 Promise 完成后的值作为数组元素。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync

1
2
3
4
Array.fromAsync(new Set([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)])).then(array =>
console.log(array)
)
// [1, 2, 3]

Array.isArray 判断是否为数组

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray

of 创建数组

通过可变数量的参数创建一个新的 Array 实例,而不考虑参数的数量或类型。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/of

1
2
3
Array.of(3, 4) // [3, 4]
Array.of(4) // [4]
Array(4) // 长度为4的稀疏数组

数组查找

at

接收一个整数值并返回该索引对应的元素,允许正数和负数。负整数从数组中的最后一个元素开始倒数。

1
2
arr.at(-1) // 获取最后一个元素,再也不用像下面这样傻傻的先计算长度了
arr[arr.length - 1] // 获取最后一个元素

indexOf 和 lastIndexOf

接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。

indexOf(): 从数组的开头(位置 0)开始向后查找。

lastIndexOf: 从数组的末尾开始向前查找。

需要注意的是 [NaN] 用 indexOf 找不到,所以添加了 includes

includes

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则 false。

参数有两个,其中第一个是(必填)需要查找的元素值,第二个是(可选)开始查找元素的位置

1
2
3
4
5
6
const array1 = [22, 3, 31, 12, 'arr']
const includes = array1.includes(31)
console.log(includes) // true

const includes1 = array1.includes(31, 3) // 从索引3开始查找31是否存在
console.log(includes1) // false

需要注意的是:includes 使用===运算符来进行值比较,仅有一个例外:NaN 被认为与自身相等。

1
2
3
let values = [1, NaN, 2]
console.log(values.indexOf(NaN)) //-1
console.log(values.includes(NaN)) //true

find 和 findIndex

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/find

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex

find()与 findIndex()方法均接受两个参数:一个回调函数,一个可选值用于指定回调函数内部的 this。

该回调函数应当在给定的元素满足你定义的条件时返回 true,而 find()和 findIndex()方法均会在回调函数第一次返回 true 时停止查找。

二者的区别是:find()方法返回匹配的值,而 findIndex()返回匹配位置的索引。

1
2
3
4
5
6
7
8
9
10
11
12
13
let arr = [1, 2, 3, 'arr', 5, 1, 9]

console.log(
arr.find((value, keys, arr) => {
return value > 2
})
) // 3 返回匹配的值

console.log(
arr.findIndex((value, keys, arr) => {
return value > 2
})
) // 2 返回匹配位置的索引

数组操作

copyWithin

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin

从数组中浅克隆一部分到当前数组的另一个位置,并不改变数组的长度, 函数有三个参数 copyWithin(target, start, end)

fill

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/fill

使用某个值对数组中的某个区域进行填充,其语法是 fill(value, start, end)

1
2
3
4
5
6
;[1, 2, 3, 5, 6].fill(7, 1, 3) // [1, 7, 7, 5, 6]   将数组下标从1到3(不包含)位置上的元素全部换成7

const k = Array(2).fill({ a: 34 })
k[0].a = 45
k[1].a // 45
k[0] === k[1] // true

join

join()方法用于把数组中的所有元素转换一个字符串。

元素是通过指定的分隔符进行分隔的。默认使用逗号作为分隔符

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/join

push 和 pop

push() 方法从数组末尾向数组添加元素,可以添加一个或多个元素。

pop() 方法用于删除数组的最后一个元素并返回删除的元素。

shift 和 unshift

shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。

unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。

sort 和 toSorted

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

sort() 方法用于对数组的元素进行排序。并返回对相同数组的引用。默认排序是将元素转换为字符串,然后按照它们的 UTF-16 码元值升序排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
function compare(value1, value2) {
if (value1 < value2) {
return -1
} else if (value1 > value2) {
return 1
} else {
return 0
}
}
arr2 = [13, 24, 51, 3]
console.log(arr2.sort(compare)) // [3, 13, 24, 51]

// 如果想降序,交换下 value1 > value2 即可

如果想要不改变原数组的排序方法,可以使用 toSorted()。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted

reverse 和 toReversed

reverse() 方法用于颠倒数组中元素的顺序。改变原数组,

如果想要不改变原数组的排序方法,可以使用 toReversed()。

concat 合并

concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/concat

slice

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice

  • slice():返回从原数组中指定开始下标到结束下标之间的项组成的新数组。
  • slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。
  • 在只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。
  • 如果有两个参数,该方法返回起始和结束位置之间的项,但不包括结束位置的项。
  • 当出现负数时,将负数加上数组长度的值来替换该位置的数

splice 和 toSpliced

很强大的数组方法,它有很多种用法,可以实现删除、插入和替换。由于会改变原数组,不想改变就用 toSpliced 新方法

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/toSpliced

  • 删除元素,返回删除的元素
1
2
3
4
var arr = ['a', 'c', 'd', 'z']
var arrRemoved = arr.splice(0, 2)
console.log(arr) //['d', 'z']
console.log(arrRemoved) //['a', 'c']
  • 向指定索引处添加元素
1
2
3
4
var arr = ['a', 'b', 'e', 'f']
arr.splice(2, 0, 'c', 'd') //[]

console.log(arr)
  • 替换指定索引位置的元素
1
2
3
4
const array1 = [22, 3, 31, 12]
array1.splice(1, 1, 8) //[3]

console.log(array1) // [22, 8, 31, 12]

toLocaleString 和 toString

将数组转换为字符串,用得不多,隐式转换里会用到需注意,具体看文档吧

flat 和 flatMap

flat 创建一个新的数组,并根据指定深度递归地将所有子数组元素拼接到新的数组中。

1
2
3
4
const arr1 = [0, 1, 2, [3, 4]]

console.log(arr1.flat())
// expected output: Array [0, 1, 2, 3, 4]

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap

flatMap() 方法对数组中的每个元素应用给定的回调函数,然后将结果展开一级,返回一个新数组。

1
2
3
4
5
6
const arr1 = [1, 2, 1]

const result = arr1.flatMap(num => (num === 2 ? [2, 2] : 1))

console.log(result)
// Expected output: Array [1, 2, 2, 1]

函数式编程方法

reduce 和 reduceRight

这两个方法都会实现迭代数组的所有项(即累加器),然后构建一个最终返回的值。

reduce()方法从数组的第一项开始,逐个遍历到最后。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

every

判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回 true。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/every

some

判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回 true。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/some

map

  • map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。
  • map() 方法按照原始数组元素顺序依次处理元素。
  • 不会改变原数组
1
2
3
4
5
var arr = [1, 2, 3, 4, 5]
var arr2 = arr.map(function (item) {
return item * item
})
console.log(arr2) //[1, 4, 9, 16, 25]

filter

创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

1
2
3
4
5
6
const words = ['spray', 'elite', 'exuberant', 'destruction', 'present']

const result = words.filter(word => word.length > 6)

console.log(result)
// Expected output: Array ["exuberant", "destruction", "present"]

forEach

forEach():对数组进行遍历循环,对数组中的每一项运行给定函数。这个方法没有返回值。参数都是 function 类型,默认有传

1
2
3
4
5
6
7
8
9
10
11
12
var arr = [11, 22, 33, 44, 55]
arr.forEach(function (x, index, a) {
console.log(x + '|' + index + '|' + (a === arr))
})

// 输出为:

// 11|0|true
// 22|1|true
// 33|2|true
// 44|3|true
// 55|4|true

迭代操作

Array.prototype.keys 这个是不是经常看到这样的 Object.keys(obj), 数组原型也有此方法,不过 Object.keys 返回的数组。而数组原型上的这个方法返回的是一个迭代器, 迭代内容则是原数组的索引

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/keys

Array.prototype.values 和 keys 一样返回一个迭代器,迭代内容是数组元素

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/values

Array.prototype.entries 同样是返回一个迭代器,迭代内容是下标和值组成的数组

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/entries