JavaScript数组总结篇

461 阅读11分钟

数组方法

一、数组增删改查

1. push 方法

  • 定义:从数组后面添加元素
  • @params:数组要新增的元素(任意数据类型,一次可添加多个,用逗号隔开)
  • @return:返回数组新增元素后的长度
  • 是否改变原数组:改变
// 使用方式: arr.push(新元素)
var arr = [1, 2, 3];
var res = arr.push(6, 7, 8);    // res = 6
console.log(arr);                // [1,2,3,6,7,8]
    

2. unshift 方法

  • 定义:从数组前面添加元素
  • @params:数组要新增的元素(任意数据类型,一次可添加多个,用逗号隔开)
  • @return:返回数组新增元素后的长度
  • 是否改变原数组:改变
// 使用方式: arr.unshift(新元素)
var arr = [1, 2, 3];
var res = arr.unshift(6, 7, 8);    // res = 6
console.log(arr);                // [6,7,8,1,2,3]
    

3. pop 方法

  • 定义:从数组后面删除元素
  • @params:无
  • @return:返回数组被删除的元素
  • 是否改变原数组:改变
// 使用方式: arr.pop()
var arr = [1, 2, 3];
var res = arr.pop();    // res = 3
console.log(arr);        // [1,2]
    

4. shift 方法

  • 定义:从数组前面删除元素
  • @params:无
  • @return:返回数组被删除的元素
  • 是否改变原数组:改变
// 使用方式: arr.shift()
var arr = [1, 2, 3];
var res = arr.shift();    // res = 1
console.log(arr);        // [2,3]
    

5. splice 方法

  • 定义:对数组任意位置元素可增删改
  • @params:不限参数, n,m,x,...第一个参数n是必传(数组的下标,代表从第n个元素起),第二个元素(可选)代表要删除(或被替代,取决于第三个参数是否有值)的元素个数,第三个参数(可选)起,代表要添加(或替代)的元素
  • @return: 返回值是一个数组,里面是删除项
  • 是否改变原数组:改变
// 使用方式: arr.splice(n, m, x)
// 删除
var arr = [1, 2, 3];
var res = arr.splice(1);    // 只传第一个参数,表示删除从下标为1的元素起,到最后一个元素 res = [2, 3]
console.log(arr);        // [1]
// arr.splice(0):可以清空数组,把原始数组中的内容基于新数组储存起来(有点类似于数组克隆)
// arr.splice(arr.length-1):删除最后一项
// arr.splice(0,1):删除第一项

// 增加
var arr = [1, 2, 3];
var res = arr.splice(1, 0, 8, 9);    // 第二个参数为0,表示不删除,之后的参数表示插进数组,下标从1开始,之前的元素往后挪
console.log(arr);        // [1, 8, 9, 2, 3]
// 改(替代)    
var arr = [1, 2, 3];
var res = arr.splice(1, 1, 8, 9);    // 第二个参数为1,表示替代掉下标为1的元素
console.log(arr);        // [1, 8, 9, 3]

二. 截取,拼接方法

6. slice 方法

  • 定义:从数组中(截取)复制一段子数组
  • @params:start, end 起始下标与结束下标,起始start必传,end不传默认复制到数组结束位置,可使用负值从数组的尾部选取元素。
  • @return:返回复制的子数组
  • 是否改变原数组:不改变
    注意:复制的数组包含start下标元素,不包含end下标元素
// 使用方式: arr.slice(start, end)
var arr = [1, 2, 3, 6, 7, 8];
var res = arr.slice(1, 4);    // res = [2,3,6]
console.log(arr);                // [1,2,3,6,7,8]
    

7. concat方法

  • 定义:合并,拼接数组
  • @params:多个任意项,可以是数组,可以是单个项
  • @return:返回合并后的新数组
  • 是否改变原数组:不改变
// 使用方式: arr.concat(项)
var arr = [1, 2, 3];
var res = arr.concat(1, [0, 0]);    // res = [1,2,3,1,0,0]
console.log(arr);                // [1,2,3]
    

三、查询方法

8. includes方法

  • 定义:用来判断一个数组是否包含一个指定的值
  • @params:参数1必传,表示要查询的元素,参数2选传,表示从指定位置查起(若为负数,从后查起,负数超过数组长度,则置为0)
  • @return:返回布尔值
  • 是否改变原数组:不改变
注意:ES6语法,在IE6-8中不兼容
// 使用方式: arr.includes(检索项)
var arr = [1, 2, 3];
var res = arr.includes(2);    // true
    

9. indexOf方法

  • 定义:用来查询检索项在数组中的位置下标
  • @params:参数1必传,表示要查询的元素,参数2选传,表示从指定位置查起
  • @return:如若检索项存在,返回其下标,没有就返回 -1
  • 是否改变原数组:不改变
// 使用方式: arr.indexOf(检索项)
var arr = [1, 2, 3];
var res = arr.indexOf(2);      // res = 1
var res1 = arr.indexOf(8);     // res = -1

10. lastIndexOf方法

  • 定义:用来查询检索项在数组中最后一次出现的位置下标
  • @params:参数1必传,表示要查询的元素,参数2选传,表示从指定位置查起
  • @return:如若检索项存在,返回其下标,没有就返回 -1
  • 是否改变原数组:不改变
// 使用方式: arr.lastIndexOf(检索项)
var arr = [1, 2, 3, 2, 2, 3, 4];
var res = arr.lastIndexOf(3);    // res = 5

四、排序,反转方法

11. sort 方法

  • 定义:对数组进行排序
  • @params:参数类型是函数
  • @return:排序后的数组
  • 是否改变原数组:改变
    注意:arr.sort() 若不传参数,数字数组只能对10以下数字排序,两位数开始默认按照每一项第一个字符来排
// 使用方式: arr.sort(fn)
var arr = [1,3,9,2,5,3,7,4,5]
// 升序
arr.sort((a, b) => a-b)      // [1, 2, 3, 3, 4, 5, 5, 7, 9]
// 降序
arr.sort((a, b) => b-a)      // [9, 7, 5, 5, 4, 3, 3, 2, 1]

12. reverse 方法

  • 定义:对数组进行反转,把数组倒过来排列
  • @params:无
  • @return:倒转排序后的数组
  • 是否改变原数组:改变
// 使用方式: arr.reverse()
var arr = [1, 2, 3, 3, 4, 5, 5, 7, 9]
arr.reverse()      // [9, 7, 5, 5, 4, 3, 3, 2, 1]

五、转化为字符串

13. join 方法

  • 定义:将数组以指定的分隔符连接起来成字符串
  • @params:指定的分隔符
  • @return:转换后的字符串
  • 是否改变原数组:不改变
// 使用方式: arr.join(指定分隔符)
var arr = [1, 2, 3, 3, 4, 5, 5, 7, 9]
arr.join('-')      // "9-7-5-5-4-3-3-2-1"
console.log(arr)   // [1, 2, 3, 3, 4, 5, 5, 7, 9]

14. toString 方法

  • 定义:将数组转换成字符串,用逗号分隔
  • @params:无
  • @return:转换后的字符串
  • 是否改变原数组:不改变
// 使用方式: arr.toString(指定分隔符)
var arr = [1, 2, 3, 3, 4, 5, 5, 7, 9]
arr.toString()      // "9,7,5,5,4,3,3,2,1"
console.log(arr)   // [1, 2, 3, 3, 4, 5, 5, 7, 9]

六、遍历与映射

1. for 循环

    for循环性能最佳,内部可以阻塞
    // 长度一般尽量先用赋值于变量,提升性能
    for(let i=0; i<len; i++) {
        ...
        continue;    // 打断当次循环,进入下次循环
        break;       // 直接打断循环,跳出循环
    }

2. forEach 方法

  • 定义:循环遍历数组,对数组的每个元素执行一次给定的函数。
  • @params:函数
  • @return:无/undefined
  • 是否改变原数组:不改变数组(若元素为引用类型,则可以改变堆空间中的值)

参数函数又接收四个参数: 参数1 => 当前循环到的元素; 参数2 => 当前循环到的元素的下标; 参数3 => forEach() 方法正在操作的数组; 参数4 => thisArg, 当执行回调函数 callback 时,用作 this 的值(即执行回调函数的对象)

注意:如果使用箭头函数表达式来传入函数参数, thisArg 参数会被忽略,因为箭头函数在词法上绑定了 this 值。

注意:除了抛出异常以外,没有办法中止或跳出 forEach() 循环,即break、continue、async/await都无效

    arr = [{ a: 1, b: 2 },{ a: 3, b: 4 }]
    arr.forEach(i => {
        i.a = i.a + i.b     // 有效
        i = {c: 2}          // 无效
    })
    console.log(arr)    // 如下图

如果数组在迭代时被修改了,则其他元素会被跳过。 示例:

3. map 方法

  • 定义:遍历数组,对数组的每个元素进行处理。
  • @params:函数
  • @return:新的数组
  • 是否改变原数组:不改变数组
var arr = [1, 2, 3]
var newArr = arr.map(function(index, item){
	return item * 2
})
// newArr = [2, 4, 6]

4. filter 方法

  • 定义:遍历数组,对数组的每个元素进行判断达到过滤目的。
  • @params:函数
  • @return:满足条件的元素组成的新数组
  • 是否改变原数组:不改变数组

// 函数的第一个参数 currentValue 为必须,代表当前元素的值。 Array.filter(function(currentValue, indedx, arr), thisValue)

// 返回数组nums中所有大于5的元素。
let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let res = nums.filter((num) => {
  return num > 5;
});
console.log(res);  // [6, 7, 8, 9, 10]

5. every 方法

  • 定义:遍历数组,对数组中每一项运行给定函数,如果该函数的每一项都返回true,则返回true,否则为false
  • @params:函数
  • @return:Boolean值
  • 是否改变原数组:不改变数组
var arr = [1, 2, 3, 4, 5]
console.log(arr.every((item, index, array) => {
  return item > 3
}))  // false

6. some 方法

  • 定义:遍历数组,对数组中每一项运行给定函数,如果该函数的至少其中一项返回true,则返回true,否则为false
  • @params:函数
  • @return:Boolean值
  • 是否改变原数组:不改变数组
var arr = [1, 2, 3, 4, 5]
console.log(arr.some((item, index, array) => {
  return item > 3
}))  // true

7. reduce 方法

语法: Array.reduce(function(accumulator, currentValue, index, array), initialValue)

  • 定义:对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值
  • @params:函数
  • @return:函数累计处理的结果
  • 是否改变原数组:否

reducer 函数接收4个参数: Accumulator (acc) (累计器) || Current Value (cur) (当前值) || Current Index (idx) (当前索引) || Source Array (src) (源数组)

reduce 第二个参数 initialValue,如果提供了initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值;如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值。

用处

// 1. 数组求和
var sum = [0, 1, 2, 3].reduce(function (accumulator, currentValue) {
  return accumulator + currentValue;
}, 0);// 和为 6

// 2. 数组去重
let arr = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd']
let newArr = arr.reduce(function (acc, current) {
  if (acc.indexOf(current) === -1) {
    acc.push(current)
  }
  return acc
}, [])  // acc 初始值为[]

// 3. 数组扁平化
let flat = [[1, 2, 3], [4, 5, 6], [7, 8, 9]].reduce((prev, cur, index, array) => {
  return [...prev, ...cur]
})   // flat = [1, 2, 3, 4, 5, 6, 7, 8]
    

8. reduceRight 方法

使用方式同上面 reduce,不同之处是reduceRight是从数组右边到左边的处理

七、其他方法

1. fill 方法

语法: arr.fill(value, start, end)

  • 定义:用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
  • @params:固定值,起始索引, 终止索引
  • @return:指定位置被填充为固定值的原数组
  • 是否改变原数组:是
// var arr = [1, 2, 3, 4]
arr.fill(0)    // arr = [0, 0, 0, 0]

// 多用于创建指定长度的空数组填充
var arr1 = new Array(3)
arr1.fill(1)   // arr1 = [1, 1, 1]

注意:若固定值为引用类型,则被填充的元素都会指向同个指针地址

2. find 方法

语法: arr.find(function(item, index, array){}, thisArg)

  • 定义:返回数组中满足提供的回调函数的第一个元素的值。否则返回 undefined。
  • @params:函数,thisAr表示执行回调时this指向的对象。
  • @return:第一个满足条件的元素或undefined
  • 是否改变原数组:是
const array1 = [5, 12, 8, 130, 44];
const found = array1.find(element => element > 10);
console.log(found);   // 12 

3. findIndex 方法

与 find 方法用法一样,不同的是findIndex返回的是元素索引下标,没找到返回 -1

八. 获取键值的方法

1. array.entries()

定义: 返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对

const array1 = ['a', 'b', 'c'];
const iterator1 = array1.entries();    // 返回一个迭代器对象
console.log(iterator1.next().value);   // [0, "a"]
console.log(iterator1.next().value);   // [1, "b"]
console.log(iterator1.next().value);   // [2, "c"]

2. array.keys()

定义: 返回一个新的Array Iterator对象,该对象包含数组中每个索引的键

const array1 = ['a', 'b', 'c'];
const iterator = array1.keys();    // 返回一个迭代器对象
for (const key of iterator) {
  console.log(key);                // 0, 1, 2              
}

3. array.values()

定义: 返回一个新的Array Iterator对象,该对象包含数组中每个索引的值

const array1 = ['a', 'b', 'c'];
const iterator = array1.values();    // 返回一个迭代器对象
for (const value of iterator) {
  console.log(value);           // 'a', 'b', 'c'
}

其他

flat方法

定义:会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

var newArray = arr.flat(depth),其中depth指定要提取嵌套数组的结构深度,默认值为 1。

用处:扁平化数组,去除空项

// 扁平化数组
var arr1 = [1, 2, [3, 4]];
newArr1 = arr1.flat();        // [1, 2, 3, 4]

var arr2 = [1, 2, [3, 4, [5, 6]]];
newArr2 = arr2.flat(2);      // [1, 2, 3, 4, 5, 6]

//使用 Infinity,可展开任意深度的嵌套数组
var arr3 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
newArr3 = arr3.flat(Infinity);     // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// 去除空项
var arr4 = [1, 2, , 4, 5];
newArr4 = arr4.flat();       // [1, 2, 4, 5]

flatMap 方法

语法:var new_array = arr.flatMap(function(current, index, array) { // return element for new_array }, thisArg)

  • 定义:首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为1的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些
  • @params: 函数, 函数运行时this指向的对象
  • @return:一个新的数组,其中每个元素都是回调函数的结果,并且结构深度 depth 值为1
  • 是否改变原数组: 否
let arr1 = ["it's Sunny in", "", "California"];
arr1.map(x => x.split(" "));
// [["it's","Sunny","in"],[""],["California"]]
arr1.flatMap(x => x.split(" "));
// ["it's","Sunny","in", "", "California"]

copyWithin 方法

语法: arr.copyWithin(target, start, end)

  • 定义:浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。
  • @params:target, 为基底的索引,复制序列到该位置, start复制的起始索引,end复制的末尾索引(不包含),start默认0, end默认到最后一个
  • @return:改变后的数组,长度不变
  • 是否改变原数组:是
const array1 = ['a', 'b', 'c', 'd', 'e'];
console.log(array1.copyWithin(0, 3, 4));  // ["d", "b", "c", "d", "e"]
console.log(array1.copyWithin(1, 3));  // ["d", "d", "e", "d", "e"]