浅谈JavaScript中的数组

272 阅读5分钟
ps:学习前端也有一段时间了,发现对JS数组的很多方法掌握的都不够彻底,写下这篇文章,当做巩固复习。

一. Javascript中想要创建一个数组有两种方法:

1、使用Array构造函数
    let arr1 = new Array();  // 创建一个空数组 length为0
    let arr2 = new Array(20); // 创建一个长度为20、值都为empty的数组
    let arr3 = new Array(1,2,3,4);  // [1, 2, 3, 4]
2、使用数组字面量
    let arr4 = []; // 空数组
    let arr5 = [1, 2]; 
    let arr6 = ['h', 'e', 'y']; // 包含字符串的数组

二. 数组方法

数组有很多方法,包括数组原型上的方法以及继承自Object对象的方法,这里只介绍数组原型的方法

按照方法是否会改变数组本身,将数组方法分为以下两类:

1、改变原数组的方法

1) push : 向数组末尾添加一个或多个元素,返回值:改变后的数组长度\color{red}{改变后的数组长度}
    let arr = [1, 2, 3, 4]; 
    let len1 = arr.push(5);
    // arr = [1, 2, 3, 4, 5]  len1 = 5
    let len2 = arr.push(6, 7);
    // arr = [1, 2, 3, 4, 5, 6, 7]  len2 = 7
2) pop : 删除数组最后一个元素,并将原数组长度减1,返回值:被删除的元素\color{red}{被删除的元素};如果原数组为空,则不改变数组,返回值:undefined\color{red}{undefined}
    let arr = [1, 2, 3, 4];
    let ele = arr.pop();
    // arr = [1, 2, 3] ele = 4
3) unshift : 向数组的第一位添加一个或多个元素,返回值:改变后的数组长度\color{red}{改变后的数组长度}
    let arr = [1, 2, 3, 4];
    let len1 = arr.unshift(0);
    // arr = [0, 1, 2, 3, 4]   len1 = 5
    let len2 = arr.unshift(-2, -1);
    // arr = [-1, -2, 0, 1, 2, 3, 4]  len2 = 7
4) shift : 删除数组的第一位元素,并将原数组长度减1,返回值: 被删除的元素\color{red}{被删除的元素};如果原数组为空,则不进行任何操作,返回值:undefined\color{red}{undefined}
   let arr = [1, 2, 3];
   let ele = arr.shift();
   // arr = [2, 3]  ele = 1
5) reverse : 颠倒数组中的顺序, 返回值:颠倒顺序后的原数组\color{red}{颠倒顺序后的原数组}
   let arr = [1, 2, 3];
   let newArr = arr.reverse();
   // arr = [3, 2, 1]  newArr = [3, 2, 1]
6) splice : 该方法可以向数组中添加或从数组中删除元素,改变原数组,返回值:被删除的元素组成的新数组\color{red}{被删除的元素组成的新数组},如果没有删除的元素,则返回:空数组\color{red}{空数组}

该方法有三个参数: arr.splice(开始截取的下标, 截取的数量, 新插入的项目) 第一个参数必填,第二个参数可选(W3School上说是必填,但是测试时发现不填也可以,默认为截取到数组最后一个元素),第三个参数可选

   let arr = [1, 2, 3, 4];
   let newArr1 = arr.splice(0);
   // 只填一个参数,表示从第0位开始截取到数组最后一位(包含)
   // arr = []   newArr1 = [1, 2, 3, 4]
   let newArr2 = arr.splice(0, 2);
   // 填写两个参数,表示从第0位开始截取,一共截取两位
   // arr = [3, 4]  newArr2 = [1, 2]
   let newArr3 = arr.splice(1, 0, 5);
   // 填写三个参数,但第二个参数为0时(即不删除数组中的元素),表示在数组下标为1的位置插入新的元素5
   // arr = [1, 5, 2, 3, 4]   newArr3 = []
   let newArr4 = arr.splice(0, 2, 5, 80);
   // 填写三个参数,表示从数组下标为0的位置开始截取,截取两位,并在该位置插入元素5,80
   // arr = [5, 80, 3, 4]  newArr4 = [1, 2]
7) sort : 用于数组排序,改变原数组。 返回值: 排序后的原数组\color{red}{排序后的原数组}
   let arr1 = ["B", "C", "A"];
   let newArr1 = arr1.sort();
   // 不接收参数时,默认以字符编码的顺序进行排序
   // newArr1 = ["A", "B", "C"]
   // 但是默认排序的结果不是我们所期待的,所有需要传入一个排序函数。sort接收的参数也只能是函数。
   let arr2 = [3, 2, 4, 1];
   let newArr2 = arr2.sort(fn)
   function fn (a, b) {
   	return a - b; // 升序排序
    return b - a; // 降序排序
    } 
    排序函数中的a为数组后一项,b为数组前一项,
    当a > b,返回一个大于0的值时,a,b无需交换位置,即按升序排序
    当a < b,返回一个大于0的值时,a,b无需交换位置,即按降序排序
    当a > b,返回一个小于0的值时,a,b交换位置,即按降序排序
    当a < b,返回一个小于0的值时,a,b交换位置,即按升序排序
8) fill : 用一个固定值填充/替换数组指定区域的值。 返回值:改变后的原数组\color{red}{改变后的原数组}
   let arr1 = [1, 2, 3, 4];
   let newArr1 = arr.fill(6);
   // 只填一个参数时,将数组内所有的内容都替换为6
   // arr1 = [6, 6, 6, 6]   newArr1 = [6, 6, 6, 6]
   let arr2 = [1, 2, 3, 4];
   let newArr2 = arr.fill(0, 1);
   // 两个参数,表示从下标为1的位置开始到数组最后一位元素的值都替换为0
   // arr2 = [1, 0, 0, 0]   newArr2 = [1, 0, 0, 0]
   let arr3 = [1, 2, 3, 4];
   let newArr3 = arr.fill(1, 1, 3);
   // 三个参数,表示从下标为1的位置开始到下标为4的位置(不包含)结束的元素值都替换为1
   // arr3 = [1, 1, 1, 4];

2、不会改变原数组的方法

1) concat : 连接两个或更多的数组,返回值:连接后的新数组\color{red}{连接后的新数组}
    let arr1 = [1, 2, 3];
    let arr2 = [4, 5};
    let newArr1 = arr1.concat(arr2);
    // newArr1 = [1, 2, 3, 4, 5]
    let arr3 = [6];
    let newArr2 = arr1.concat(arr2, arr3);
    // newArr2 = [1 , 2, 3, 4, 5, 6]
2) join : 将数组中的所有元素按照指定分隔符(默认以,为分隔符)放入一个字符串,不改变原数组,返回值:一个字符串\color{red}{一个字符串}
   let arr = [1, 2, 3];
   let newStr1 = arr.join();
   let newStr2 = arr.join('.');
   // arr = [1, 2, 3]   newStr1 = "1,2,3"  newStr2 = "1.2.3"
3) slice : 从已有数组中截取指定位数的值,不改变原数组,而是生成一个新的子数组,返回值:新的子数组\color{red}{新的子数组}
   let arr = [1, 2, 3, 4];
   let newArr1 = arr.slice(0, 2);
   // 两个参数,第一个表示从第几位开始截取,第二个参数表示截取到数组第几位的元素下标(不包含)
   // newArr1 = [1, 2]   arr = [1, 2, 3, 4]
   let newArr2 = arr.slice(1);
   // 第二个参数可省略,省略时默认截取到数组最后一位
   // newArr2 = [2, 3, 4]
   let newArr3 = arr.slice(-3, -1);
   // 两个参数都可以为负值,当参数为负值时,表示从数组的末尾开始计算,即:-1为数组最后一个元素,-2为数组倒数第二个元素。 
   // newArr3 = [2, 3]
4) toString : 将数组转换为字符串。返回值:转换后的字符串\color{red}{转换后的字符串}
   let arr = [1, 2, 3];
   let newStr = arr.toString();
   // arr = [1, 2, 3]   newStr = "1, 2, 3"
5) includes : 判断当前数组是否包含指定的值,返回值:Boolean\color{red}{Boolean}
   let arr = [1,'2',3];
   let res1 = arr.includes(1, 1);
   // 填写两个参数,第二个参数表示从索引为1开始查找
   // res1 = false
   let res2 = arr.includes(1);
   let res3 = arr.includes(2);
   // 只填写一个参数,表示从索引为0开始查找
   // res1 = true   res = false
6) indexOf : 判断当前数组是否包含指定的值,返回值:第一个匹配上的值的索引\color{red}{第一个匹配上的值的索引};如果不包含指定值,则返回值:1\color{red}{-1}
   let arr = [1, 2, '3'];
   let res1 = arr.indexOf(1, 2);
   // 填写两个参数,第一个参数表示要查找的值,第二个参数表示从数组索引为2开始查找
   // res1 = -1
   let res2 = arr.indexOf(1);
   let res3 = arr.indexOf(3);
   let res4 = arr.indexOf(2);
   // 只填写一个参数,第二个参数则默认从索引0开始查找
   // res2 = 0, res3 = -1  res4 = 1

数组迭代方法 : 以下方法都接收一个函数作为参数

7) forEach : 调用数组的每一个元素,并将每个元素都传递给回调函数。返回值:undefined,也可理解成无返回值\color{red}{undefined,也可理解成无返回值}
   let arr = [1,2,3,4];
   let res = arr.forEach( (item, index, arr) => {
      // item:当前元素   index:可选,当前元素索引  arr:可选,当前元素所属数组
      // 可以对数组内每一个元素进行一些相同的操作
   }, thisValue)
   // thisValue 传递给函数的值一般用 "this" 值。可选,默认为undefined
   // res = undefiend
8) for...in : 可以用于遍历数组或对象的属性。
   let arr = [1,2,3];
   for (let index in arr) {
     // 该方法遍历数组时遍历的是数组索引
     // do something
   }
9) for...of : 可以用于遍历数组的值。
   let arr = [1,2,3]
   for(let item of arr) {
     // 该方法遍历的是数组的值
     // do something
   }
10) map : 按照原数组元素顺序依次处理元素。返回值:处理后的元素组成的新数组\color{red}{处理后的元素组成的新数组} 注:对空数组不会进行任何操作
   let arr = [1,2,3];
   let res = arr.map( (item, index, arr) => {
      // 接收参数和forEach一样,区别是有 有意义的返回值,
      return item ++;
   }, thisValue )
   // arr = [1,2,3]   res = [2,3,4]
11) reduce : 接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,返回值:累加过后的总值\color{red}{累加过后的总值}
  let arr = [1,2,3,4];
  let res = arr.reduce( (total, num, index, arr) => {
     // total : 初始值,即initial传进来的值
     // 其它三个参数与forEach相同
     return total + num;
  }, 0[initial] )
  // res = 10, 1+2+3+4。 
12) filter : 创建一个新数组,新数组中的元素是原数组中满足条件的所有元素。返回值:新数组\color{red}{新数组}。不会对空数组进行任何操作
   let arr = [1,2,3,4];
   let res = arr.filter( (item, index, arr) => {
      return item > 2;
   }, thisValue)
   // res = [2, 3]