JS数组厨房

236 阅读7分钟

方法汇总

基本操作

方法参数描述改变原数组
push()item向数组的尾部插入一个或多个item,return该数组的新长度true
pop()删除数组中的最后一个元素,return被删除的元素true
unshift()item在数组头部插入一个或多个item,return该数组的新长度true
shift()删除数组中的第一个元素,return被删除的元素true


var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// 类似于栈(stack),后进先出(last in, first out)
arr.push(10); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arr.pop(); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// 类似于队列(queue),先进先出(first in, first out)
arr.unshift(-1); // [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
arr.shift(); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


常用方法

方法参数描述改变原数组
indexOf()itemreturn item 在数组中的第一次出现的索引值(找不到return -1)false
lastIndexOf()itemreturn item 在数组中的最后一次出现的索引值(同上)false
slice()startIndex, endIndex按索引切割数组,return新的数组false
splice()index, deleteCount, item从数组中删除指定的一个或多个元素,return新的数组true
concat()item连接两个或多个数组,return新的数组false
join()separator将数组用分隔符做间隔转换为字符串并returnfalse
reverse()反转数组,return反转后的数组true
sort()fn对数组的元素,默认按照Unicode编码,从小到大进行排序true


// 寻找元素indexOf(item)
arr.indexOf(0); // 0
arr.lastIndexOf(0); // 0

// 切割数组slice(startIndex, endIndex)
arr.slice(2, 3); // [2]
arr.slice(2, 4); // [2, 3]
arr.slice(2); // [2, 3, 4, 5, 6, 7, 8, 9]
var brr = arr.slice() // 复制新数组

// 修整数组splice(index, deleteCount, item)
// 增:在数组头部增加元素-1, return被删除的数组元素组成的数组
arr.splice(0, 0, -1); // [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// 删:在元素0索引处删除一个元素
arr.splice(arr.indexOf(0), 1); // [-1, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 // 改:将第一个元素换成0
arr.splice(0, 1, 0); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

// 合并数组concat(anotherArray)
var arr1 = [1, 2];
var arr2 = [3, 4];
var str = 'hhhdaweads' // str当成一个元素的数组处理
console.log(arr1.concat(arr2, str)); // [1, 2, 3, 4, 'hhhdaweads']

// 合并数组为字符串join(分隔符)
console.log(arr.join(' ')); // "0 1 2 3 4 5 6 7 8 9"

// 倒转数组reverse()
console.log(arr.reverse()); // [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

// 数组排序sort()
console.log(arr.sort()); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


遍历数组

方法参数描述改变原数组
forEach()cb(item, index, arr), thisArg对数组进行遍历,无return值false
filter()cb(item, index, arr), thisArg遍历基础上,通过回调return的布尔值来筛选元素,最终return一个筛选后的新数组false
map()cb(item, index, arr), thisArg遍历基础上,通过回调的return值取得新元素,最终return映射产生的新数组false
find()cb(item, index, arr), thisArg遍历数组,一旦回调返回true(找到了),即跳出循环,return找到的元素,找不到则return undefinedfalse
findIndex()cb(item, index, arr), thisArg遍历数组,一旦回调返回true(找到了),即跳出循环,return找到的元素索引,找不到则return -1false
some()cb(item, index, arr), thisArg遍历数组,一旦回调返回true(有一个符合条件),即跳出循环,return true,若没有则return falsefalse
every()cb(item, index, arr), thisArg遍历数组,一旦回调返回false(需所有符合条件),即跳出循环,return false ,若没有则return truefalse
reduce()cb(acc, item, index, arr), initialValue遍历数组,进行累积操作。acc是每一次循环的累积值,从上一次循环的回调中return出来。acc初始为initialValue,循环从索引1开始。若initialValue没提供,acc初始为索引1的元素,循环从索引2开始。最终return累积的结果false
reduceRight()cb(acc, item, index, arr), initialValue同上,不过从右往左来进行累积false

传统方法

for (let i = 0; i < arr.length; i++) {
    const item = arr[i];
    console.log(item);
}
for (let item of arr) {
    console.log(item);
}

forEach遍历

// arr.forEach(callbackfn: (item, index, array) => void, thisArg): void
// item 必需。当前元素
// index 可选。当前元素的索引值。
// arr 可选。当前元素所属的数组对象。
// thisArg 可选。即回调函数内的this指向。如果这个参数为空, 回调中this将是"undefined"
// 本身不会改变数组,但callback中可能改变。
// 无return值
// 深入: 
// thisArg本质上是符合function的this的一般情况的。
// forEach()所持有的数组范围是在第一次callback之前决定的:callback时
// 增加数组长度来增加循环次数是不可行的!
// 范围提前决定,但值可以在callback时改变,访问到第一个元素改
// 第二个元素的值,访问第二个时的值是改过的版本。删除掉的话则跳过不会访问到!
// 中途修改元素如shift()可以导致跳过一个iteration
// 遇上[0, 1, , 3]的情况(即有未赋值的元素),会被callback跳过
// 无法中断:break不起作用
arr.forEach((item, index, arr) => {
    console.log(item, index);
}, this)
// 此处传了this进去其实并没用,因为箭头函数的this默认跟随父作用域。改成普通function即可。

filter过滤

// arr.filter(callbackfn: (item, index, array) => Boolean, thisArg): newArr
// return新的arr
// 参数理解与上面forEach一致
// 根据回调函数return值true或false来判断是否将该元素扔进新数组
console.log(arr.filter(item => item % 3 === 0)); // [0, 3, 6, 9] 

map映射

// arr.map(callbackfn: (item, index, array) => any, thisArg): newArr
// 将回调函数的return值扔进新数组
console.log(arr.map(item => item * 10)); // [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

find寻找

// arr.find(callbackfn: (item, index, array) => Boolean, thisArg): 找到的item/undefined
// arr.findIndex(callbackfn: (item, index, array) => Boolean, thisArg): 找到的item索引值/-1
// 这两个方法都是会遍历数组,一旦找到了就跳出循环
// 返回找到的元素(的索引),否则返回undefined(-1)
console.log(arr.find(item => item > 10)); // undefined
console.log(arr.findIndex(item => item > 7)); // 8

some/every测试

// arr.some(callbackfn: (item, index, array) => Boolean, thisArg): true / false
// arr.every(callbackfn: (item, index, array) => Boolean, thisArg): true / false
// some: 当找到了有一个元素符合回调函数条件返回了true后,循环中断,得到true;
// 若无符合条件的最终返回false
// every: 与some相反,有一个false即中断返回false,否之true
console.log(arr.some(item => item > 0)); // true
console.log(arr.every(item => item > 0)); // false

reduce累积

// arr.reduce(callbackfn: (accumulator, currentValue, currentIndex, array) => value, initialValue)
// arr.reduceRight(callbackfn: (accumulator, currentValue, currentIndex, array) => value, initialValue)
// 回调中后三个参和上面理解一样,多出来的accumulator是每次循环返回值的累积
// initialValue若无,则accumulator初始为数组索引为1的元素,循环从索引2的元素开始
// 若有,accumulator则为initialValue,循环从索引为1开始
// reduceRight则是将数组从右往左来循环累积
console.log(arr.reduce((a, b) => a + b)); // 45
console.log(arr.reduceRight((a, b) => a + b)); // 45

冷门但实用的方法

方法参数描述改变原数组
Array.isArray()value对value进行判断,是数组则return true
Array.from()arrayLike, mapFn, thisArg将类似数组或可遍历的对象转换成数组,return新数组
Array.of()item根据item来创建一个新的数组
flat()level对嵌套的数组进行扁平化操作,return新数组false
fill()value, startIndex, endIndex对数组元素进行批量填充操作true
includes()item, index判断数组是否含有某元素,return Booleanfalse

// Array.isArray()
// 检测value是否是一个数组对象
console.log(Array.isArray([1, 2])); // true
console.log(Array.isArray('1, 2')); // false

// Array.from(arrayLike, mapFn, thisArg)
// arrayLike即类似数组或可遍历的对象,mapFn即映射函数,像融入了map方法
console.log(Array.from('foo')); // ['fo', 'o', 'o']
console.log(Array.from([1, 2, 3], x => x + 1)); // [2, 3, 4]


// Array.of(item)
// 用来new一个数组,很像new Array(),唯一区别是当放入一个数字时,前者处理为元素,后者处理为长度并填充为空
console.log(Array.of(5)); // [5]
console.log(new Array(5)); // [ , , , , ]

// arr.flat(level)
let deepArr = [1, [2,3], [4, [5, 6]]]
console.log(deepArr.flat()); // [1, 2, 3, 4, [5, 6]]
console.log(deepArr.flat(2)); // [1, 2, 3, 4, 5, 6]
console.log(deepArr.flat(Infinity)); // [1, 2, 3, 4, 5, 6]

// arr.fill(value, startIndex, endIndex)
// value为非primitive(object)的话,就会创建很多个地址引用,而不是很多个新的object
// endIndex省略后默认填充到最后,startIndex也省略的话默认为0
var brr = new Array(10) // 新建长度为10,默认填充为空(非undefined)的brr
console.log(brr); // [ , , , , , , , , , ]
brr.fill(0)
console.log(brr); // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

// arr.includes(item, index)
// item: 要查找的元素
// index: 开始查找的索引值,默认为0
// return值为Boolean
console.log(arr.includes(1)); // true