Skip to content

一、数组的定义和基本使用

1. 数组简介和定义

  • 数组(Array),顾名思义,用来存储一组相关的值,从而方便进行求和、计算平均数、逐项遍历等操作。

    js
      var scoreArr = [96, 07, 76, 87, 100];
  • 数组是非常重要的一种数据结构

  • 数组的定义

    js
       var arr = ['A', 'B', 'C'];
       // 或者
       var arr = new Array('A', 'B', 'C'); 
       // 或者 但是值都是 undefined
       var arr = new Array(4);
  • 访问数组项

    • 数组每一项都有下标,下标从0开始
    • 可以使用方括号中书写下标的形式,访问数组的任一项。
  • 下标越界

    • JavaScript规定,访问数组中不存在的项会返回undefined,不会报错。
  • 数组的长度

    • 数组的length属性表示它的长度
    • 数组最后一项的下标是数组的长度减1
  • 更改数组项

    • 如果更改的数组项超过了length-1,则会创造这项。
  • 数组的遍历

    • 数组的最大的优点就是方便遍历

2. 数组类型的检测

  • 数组用typeof检测结果是object
  • Array.isArray()方法可以用来检测数组。

二、 数组的常用方法

1. 数组的头尾操作

方法功能
push()在尾部插入新项
pop()在尾部删除
unshift()在头部插入新项
shift()在头部删除
  • push()方法

    • push()方法用来在数组末尾推入新项,参数就是推入的项。
    • 如果要推入多项,可以用逗号隔开。
    • 调用push()方法后,数组会立即改变,不需要赋值。
  • pop方法

    • push()方法相反,pop()方法用来删除数组中的最后一项
    • pop()方法不仅会删除数组末项,而且会返回被删除的项。
  • unshift()方法

    • unshift()方法用来在数组头尾插入新项,参数就是要插入的项。
    • 如果要插入多项,可以用逗号隔开。
    • 调用unshift()方法后,数组会立即改变,不需要赋值。
  • shift()方法

    • unshift()相反,shift()方法用来删除数组中下标为0的项
    • shift()方法不仅会删除数组首项,而且会返回被删除的项。

2. 数组的常用方法:splice slice

  • splice()方法

    • splice()方法用于替换数组中的指定项
      js
        var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
        arr.splice(3, 2, 'X', 'Y', Z);
        console.log(arr); //  ['A', 'B', 'C', 'X', 'Y', 'Z', 'F', 'G']
    • splice()方法用于在指定位置插入新项
      js
        var arr = ['A', 'B', 'C', 'D'];
        arr.splice(2, 0, 'X', 'Y', 'Z');
        console.log(arr); // ['A', 'B', 'X', 'Y', 'Z', 'C', 'D']
    • splice()方法可以用于删除指定项
      js
        var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
        arr.splice(2, 4); // 没有设置替换的新项,仅删除4项
        console.log(arr); // ['A', 'B', 'G']
    • splice()方法会以数组形式返回被删除的项
  • slice()方法

    • slice()方法用于得到子数组
    • slice(a, b)截取的子数组`从下标为a的项开始,到下标为b(但不包括下标为b的项)结束
    • slice(a, b)方法不会更改原有数组。
    • slice()如果不提供第二个参数,则表示从指定项开始,提取所有后续所有项作为子数组
    • slice()的参数允许为负数,表示数组的倒数第几项

3. 数组的常用方法:join split concat reverse indexOf includes

  • join()的参数表示以什么字符作为连接符,如果留空则默认以逗号分割,如同调用toString()方法
  • split()的参数表示以什么字符拆分字符串,一般不能留空。
  • concat()方法
    • concat()方法可以合并连结多个数组
    • concat()方法不会改变原数组。
  • reverse()方法用来将一个数组中的全部项顺序置反。
  • indexOf()includes()方法
    • indexOf()方法的功能是搜索数组中的元素,并返回它所在的位置,如果元素不存在,则返回-1
    • includes()方法的功能是判断一个数组是否包含一个指定的值,返回布尔值。

三、数组算法

1. 遍历相关算法

  • 求数组中每一项的总和、平均数
    js
      // 求数组的总和和平均数
      var arr = [3, 5, 3, 2, 1, 1];
      // 累加器
      var sum = 0;
      // 遍历数组,每遍历一个数字,就要把这个数字累加到累加器中
      for (var i = 0; i < arr.length; i++) {
          sum += arr[i];
      }
      console.log(sum);
      console.log(sum / arr.length);
  • 求数组项的最大值和最小值
    js
      // 求数组的最大值和最小值
      var arr = [3, 4, 88, 3, 1];
      // 定义两个变量,max表示当前寻找到的最大值,默认是arr[0]
      //             min表示当前寻找到的最小值,默认是arr[0]
      var max = arr[0];
      var min = arr[0];
      // 遍历数组,从下标为1的项开始遍历
      for (var i = 1; i < arr.length; i++) {
          // 如果你遍历的这项,比当前最大值大,那么就让当前最大值成为这个项
          if (arr[i] > max) {
              max = arr[i];
          } else if (arr[i] < min) {
              // 否则如果你遍历的这项,比当前最小值小,那么就让当前最小值成为这个项
              min = arr[i];
          }
      }
      console.log(max, min);

2. 数组去重和随机样本

  • 去掉数组中的重复项
    • 思路:准备一个空结果数组,遍历原数组,如果遍历到的项不在结果数组中,则推入结果数组。
      js
        var arr = [1, 1, 1, 2, 2, 3, 3, 3, 2, 1];
        // 结果数组
        var result = [];
        // 遍历原数组
        for (var i = 0; i < arr.length; i++) {
            // 判断遍历到的这项是否在结果数组中,如果不在就推入
            // includes方法用来判断某项是否在数组中
            if (!result.includes(arr[i])) {
                result.push(arr[i]);
            }
        }
        console.log(result);
  • 请随机从原数组中取3项
    • 思路:准备一个空结果数组,遍历原数组,随机选择一项,推入结果数组,并且将这项删除。
      js
        var arr = [3, 6, 10, 5, 8, 9];
        // 结果数组
        var result = [];
        // 遍历原数组
        for (var i = 0; i < 3; i++) {
            // 随机选择一项的下标,数组的下表0~arr.length - 1;
            // 之前学习过一个random的公式,[a,b]区间的随机数是parseInt(Math.random() * (b-a+1)) + a;
            var n = parseInt(Math.random() * arr.length);
            // 把这项推入结果数组
            result.push(arr[n]);
            // 删除这项,防止重复被随机到
            arr.splice(n, 1);
        }
        console.log(result);

3. 冒泡排序

  • 冒泡排序的核心思路是一趟一趟地进行多次项的两两比较,每次都会将最小的元素排好位置,如同水中的气泡上浮一样。
  • 4个数字,共需要比较3趟,比较次数为3 + 2 + 1 = 6
  • n个数字,共需要比较n-1趟,比较次数为n(n-1)/2
    js
        // 冒泡排序
        var arr = [6, 2, 9, 3, 8, 1, 45, 23, 45, 49];
        // 一趟一趟比较,趟数序号就是i
        for (var i = 1; i < arr.length; i++) {
            // 内层循环负责两两比较
            for (var j = arr.length - 1; j >= i; j--) {
                // 判断项的大小
                if (arr[j] < arr[j - 1]) {
                    // 这一项比前一项还小了,那么就要交换两个变量的位置
                    var temp = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
            console.log(arr);
        }
        console.log(arr);

4. 二维数组

  • 二维数组:以数组作为数组元素的数组,即"数组的数组"。
  • 二维数组可以看做是矩阵。
    js
        var matrix = [
            [11, 33, 55],
            [22, 33, 44],
            [36, 49, 52],
            [56, 10, 23]
        ];
        console.log(matrix.length);     // 4
        // 循环输出二维数组中的每一个项
        for (var i = 0; i < 4; i++) {
            for (var j = 0; j < 3; j++) {
                console.log(matrix[i][j]);
            }
        }

4. 引用类型

  • 相等判断时的区别
    • 基本类型进行相等判断时,会比较值是否相等
    • 引用类型进行相等判断时,会比较址是否相等,也就是说它会比较是否为内存中的同一个东西。
  • 总结
    举例当var a = b变量传值时当用 == 比较时
    基本类型值数字型、字符串型、布尔型、undefined型内存中产生新的副本比较值是否相等
    引用类型值对象、数组内存中不产生新的副本,而是让新变量指向同一个对象比较内存地址是否相同,即比较是否是同一个对象

5. 深克隆和浅克隆

  • 使用arr1=arr2的语法不会克隆数组
  • 浅克隆:只克隆数组的第一层,如果是多维数组,或者数组中的项是其他引用类型值,则不克隆其它层。
  • 深克隆:克隆数组的所有层,要使用递归技术。
    js
      var arr1 = [1, 2, 3, 4, [6, 9, 4]];
      // 结果数组
      var result = [];
      // 遍历原数组中的每一项,把遍历到的项推入到结果数组中
      for (var i = 0; i < arr1.length; i++) {
          result.push(arr1[i]);
      }
      console.log(result);
      console.log(result == arr1);    // 期望false,因为引用类型值进行比较的时候,等等比较的是内存地址
      console.log(result[4] == arr1[4]);  // 藕断丝连

6. 重点内容

  • 数组是什么?应该如何定义?
  • 如何检测数组类型?
  • 数组有哪些常用方法?
  • 数组的遍历相关算法、去重和随机样本、冒泡排序?
  • 基本类型值和引用类型值的区别
  • 实现浅克隆

Released under the MIT License.