JavaScript数组方法持续更新
作为 js 的重要一员,一定要好好了解一番,若有理解不到之处,还望不吝指教。
何为数组,是有序的集合。
一、如何判断是否是数组
-
Array.isArray()
字面上的理解,是不是一个数组。let arr = [] let str = '[]' Array.isArray(arr) // true Array.isArray(str) // false
-
instanceof
是不是Array
的实例。let arr = [] let str = '[]' arr instanceof Array // true str instanceof Array // false
-
constructor
, 实例对象的隐式原型指向对象的构造函数。let arr = [] arr.constructor === Array // true
-
Object.prototype.toString.call(arr) === '[object Array]'
let arr = [] Object.prototype.toString.call(arr) === '[object Array]' // true
二、创建数组
-
字面量
let arr = []
-
new Array()
let arr = new Array()
-
split()
let str = '1,2,3' let arr = str.split(',')
-
Array.from()
// 将字符串转换成数组 let str = '123' let arr = Array.from(str) // ["1","2","3"] // 将 arguments 伪数组转换为数组 Array.from(arguments) // 将 dom 元素伪数组转换为数组 Array.from(document.querySelectorAll('div'))
Array.from 接受3个参数
- 第一个参数必填,需要转换的对象
- 第二个可选,接受一个回调函数,数组中的每一项都会回调该函数
- 第三个可选,绑定回调函数的 this 指向
-
Array.of()
无论什么类型,包裹一层变成数组Array.of() Array.of('') Array.of(null) Array.of(undefined) Array.of(NaN) Array.of(()=>{}) Array.of({}) Array.of(123)
三、数组的方法
关注一个方法或者函数,主要关注以下几点
- 参数
- 返回值
常用的数组方法
不改变原数组
forEach map filter some every find findIndex concat indexOf lastindexOf slice flat includes
join reduce
改变原数组
push unshift pop shift splice fill sort reverse
-
forEach()
/* 接受 2 个参数 * 第一个参数必填,回调函数 * 第二个参数,绑定回调函数的 this 指向, (例子里的 obj) */ Array.forEach( (item,index,Array) => { // item 表示数组当前循环到的项 // index 表示数组当前循环项的下标值 // Array 表示原数组 },obj)
forEach 不能中断循环(break),只能跳过当前循环项,进入下一项的循环。
该方法返回值为 undefined
-
map()
, 参数同 forEach 方法。// 不能直接跳出循环 break 会报错, return 也不行 let arr = [1,2,3] let res = arr.map((item)=>{ return item + 1 })
返回值为一个新的数组,不改变原来的数组。
-
filter()
, 一般用来过滤数组中的元素,参数同 forEach 方法let obj = {} let arr = [ { id: 1, }, { id: 2, }, { id: 3, }, ] let newArr = arr.filter((item, index, Array) => { // 必须 return ,且新数组只会含有条件为 true 的项 return item.id == 2 }, obj) console.log(newArr) // [{id: 2}]
返回值为一个新数组,不改变原数组
-
some()
,参数同 forEacharr.some( (item, index, Array) => { // 有一项满足条件,则返回 true ,剩余的项不在参与循环;没有满足条件,返回 false // 有点 逻辑 || 的意思,只是参与的项不同。 return item.id === 2 }, obj)
返回值 Boolean 类型, true or false
-
every()
,参数同 forEach/* 和 some() 方法相似,有一项是 false 则终止循环,返回 false,每一项都是 true ,返回 true * 这个完全和 && 的思想一致 */
返回值 Boolean 类型, true or false
tips: 空数组是个特例,始终返回 true
-
find()
,参数同 forEach/* * 找到匹配的项则返回第一个匹配项,循环终止;找不到则返回 undefined */
返回值,匹配的项 或者 undefined
-
findIndex()
,参数同forEach// 匹配到选项则返回第一个匹配项的索引,循环终止,否则返回 -1
返回值,匹配到的下标值 或者 -1
-
push()
// 在数组的最后增加元素 let arr = [1,2] arr.push(3) // 一个参数 let res = arr.push(4,5,6) // 多个参数 console.log(res) // [1, 2, 3, 4, 5, 6] console.log(arr) // 6
返回数组的长度,并改变原数组
-
unshift()
let arr = [1,2] arr.unshift(0) // 3
返回数组的长度,并改变原数组
-
pop()
, 不需要参数// 从数组的最后开始删除一个元素 let arr = [1,2] arr.pop() // 2
返回被删除元素,空数组删除返回 undefined,改变原数组,
-
shift()
, 不需要参数// 从数组的开头开始删除一个元素 let arr = [1,2] arr.shift() // 1
返回被删除元素,空数组删除返回 undefined,改变原数组,
-
concat()
, 拼接数组let arr = [1, 2] let arr1 = [3, 4] let arr2 = [5, 6] let newArr = arr.concat(arr1, arr2) // 数组的拼接 let newArr2 = newArr.concat() // 数组的浅拷贝
返回值为新的数组, 不改变原来的数组
-
indexOf()
与lastIndexOf()
// 找到第一次匹配元素的索引值,否则返回 -1 let arr = [1,2,3,4] arr.indexOf(2, 0) // 从索引为 0 的位置开始向数组的末尾查找 arr.lastIndexOf(2, arr.length-1) // 从索引为 arr.length-1 的位置开始向数组的开头查找
返回值为匹配的下标 或者 -1
-
slice()
, 浅拷贝数组let arr = [1,2,3,4,5,6] // 包含开始位置, 不包含结束位置 arr.slice(1,2) // [2]
返回值 新的数组, 不改变原数组
-
splice()
, 万金油的存在,增、删、改功能。let arr = [1, 2, 3] /* 删除功能,任意位置删除 * 参数1. 开始的索引位置,包含该位置 * 参数2. 删除的个数 * 返回值:返回删除的元素的一个数组,改变原数组 */ arr.splice(0, 1) // [1] console.log(arr) // [2, 3] /* 增加功能,任意位置增加元素 * 参数1. 开始的索引位置,也可以理解为新数组的索引位置上插入新的项。 * 参数2. 删除个数为 0 * 参数3. 增加的项 * 返回值:空数组,改变原数组 */ arr.splice(1, 0, 1, 2, 3) // [] console.log(arr) // [2, 1, 2, 3, 3] /* 修改功能,任意位置修改,这个就是增加功能的变形 * 参数1. 开始索引位置,包含该位置 * 参数2. 替换的个数 n,包含从索引参数1开始在内的向后 n 项将会从数组去除 * 参数3. 替换的项, 在数组索引参数1位置,向后插入替换的项 * 返回值: 空数组,改变原数组 */ arr.splice(1, 2 ,{id:1},{id:2})
主要是参数的灵活运用,组成不同的功能,很实用。
-
copyWithin()
/* 从数组内部替换自身项 * 参数1. 替换元素开始的位置 * 参数2. 从该索引开始复制数据,默认是0 * 参数3. 复制数据结束的索引值,不包含该位置,默认到数组的结束 * 返回值:修改后的新数组 */ let arr = [1, 2, 3, 4] arr.copyWithin(0,1,2) // [2,2,3,4]
返回值为新的数组,改变原数组
-
fill()
/* 填充数组 * 参数1. 用来填充数组的值 * 参数2. 起始索引值,默认是 0 * 参数3. 终止索引值,不包含该项,默认是数组的长度 */ let arr = [] arr.fill(1, 0, 10) // 无法改变空数组,只能改变已有的项 arr = [1, 2, 3, 4] arr.fill(5, 1 ,2) // [1,5,3,4]
返回值为改变后的数组,改变原数组
-
flat()
/* 多维数组变成一维数组 * 参数 指定展开嵌套数组的深度,Infinity 表示任意深度 * 不传可以去除数组中的空项 * 返回值:新的的数组,不改变原数组 */ let arr = [1, 2, [3, 4]] arr.flat(1) // [1, 2, 3, 4] let arr1 = [1, 2, 3, , ,4] arr1.flat() // [1, 2, 3, 4]
返回值:新的的数组,不改变原数组
-
flatMap()
,参数同 forEach/* 循环数组,每一项执行一个函数,最终执行以下flat()方法 * 返回值:新的数组,不会改变原数组 */ let arr = [1, 2] arr.flatMap( (item) => { [item, item * 2] }) // [1,2,2,4]
flatMap 只能展开一层数组
-
includes()
/* 判断数组是否含有某个指定的值 * 参数1. 包含项 * 参数2. 检索的开始位置,包含该位置 * 返回值:包含返回 true , 不包含返回 false */ console.log([1, 2, 3].includes(3)); // true console.log([1, 2, 3].includes(3, 3)) // false console.log([1, 2, 3].includes(3, 2)) // true
也可用于字符串的检索,区分大小写
-
sort()
/* 排序 * 参数1. * 参数2. * 规则 * - 不传值,则是转化为字符串逐位比较 ASCII 大小 * - 接收一个函数,函数有个两个参数 a b * 若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。 * 若 a 等于 b,则返回 0。 * 若 a 大于 b,则返回一个大于 0 的值。 * 返回值:新的排序后的数组 */ let arr = [1,5,2,10] arr.sort((a, b) => { // a - b 返回值为正数,则交换两项的位置 return a - b }) // [1,2,5,10] 从小到大 arr.sort((a, b) => { return b - a }) // [10,5,2,1] 从大到小
返回值为有序的新数组,改变原数组
-
reverse()
let arr = [1, 2, 3] arr.reverse() // [3, 2, 1]
反转数组,改变原数组
-
toLocaleString()
和toString()
/* 将数组的每一项使用 toLocaleString 或者 toString * 不同点是语言环境的不同 * 返回值:字符串,不改变原数组 */ let arr = [1, 'a', { id: 1 }, new Date()] // 1,a,[object Object],2020/5/22 下午2:44:40 console.log(arr.toLocaleString()) // 1,a,[object Object],Fri May 22 2020 14:44:40 GMT+0800 (中国标准时间) console.log(arr.toString())
返回值:字符串,不改变原数组
-
join()
/* 将数组使用特定的符号进行分割 * 返回值:字符串,不改变原数组 */ let arr = [1, 2, 3] arr.join() // 1,2,3 arr.join('') //123 arr.join('*') //1*2*3
和 split 更配哦
-
reduce()
, 实用且重要的方法。/* 累加和累计这种描述特贴切 * 参数1. 一个处理函数,接收 4 个参数 * - pre 第一次为参数2的值,然后是每次 处理函数 返回的值 * — val 当前循环项 * - index 当前循环项索引 * — arr 当前数组 * 参数2. 第一次 pre 的值,默认是数组的第一个值。 */ let str = '好好学习天天向上' let arr = str.split('') let i = 0 let res = arr.reduce((pre, val, index, arr) => { console.log(i++) console.log(`pre:${pre}`) console.log(`val:${val}`) return pre + val }, '我会') console.log(res) // 我会好好学习天天向上
返回值为累计的结果,不会改变原数组
-
reduceRight()
和 reduce 的结果一样,不同的是从数组的最后开始。
参考
[ MDN ]:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array
[ 掘金 ]: https://juejin.im/post/5d1ff6def265da1b855c777f#heading-22