JavaScript 数组

758 阅读6分钟

数组

基本概念

  1. 什么是数组? 数组就是专门用于存储一组数据的东西 注意点:
    • 和我们前面学习的 number/ string/ boolean/ null/ undefined不同(基本数据类型)
    • 而数组 (array) 不是基本数据类型, 是引用数据类型(对象类型)
  2. 如何创建一个数组? let 变量名称 = new Array(size);
  3. 如何操作数据
    • 存储数据 变量名称[索引号] = 需要存储的数据;
    • 获取存储的数据 变量名称[索引号];

注意点

  1. 和其它编程语言不同, 如果数组对应的索引中没有存储数据, 默认存储的就是 undefined 其它编程语言中默认保存的是垃圾数据或者 0

  2. 和其它编程语言不同, JavaScript 中访问了数组中不存在的索引不会报错, 会返回 undefined 其它编程语言一旦超出索引范围就会报错或者返回脏数据

  3. 和其它编程语言不同, 当 JavaScript 中数组的存储空间不够时数组会自动扩容 其它编程语言中数组的大小是固定的

  4. 和其它编程语言不同, JavaScript 的数组可以存储不同类型数据 在其它编程语言中数组只能存储相同类型数据 (要么全部都是字符串, 要么全部都是数值等)

  5. 和其它编程语言不同, JavaScript 中数组分配的存储空间不一定是连续的 其它语言数组分配的存储空间都是连续的, JavaScript 数组是采用"哈希映射"方式分配存储空间 什么是哈希映射? 好比字典可以通过偏旁部首找到对应汉字, 我们可以通过索引找到对应空间


    在浏览器中各大浏览器也对数组分配存储空间进行了优化

    • 如果存储的都是相同类型的数据, 那么会尽量分配连续的存储空间
    • 如果存储的不是相同的数据类型, 那么就不会分配连续的存储空间
  6. 创建数组的方式

    1. 通过构造函数创建数组

      let 变量名称 = new Array(size); // 创建一个指定大小数组
      let 变量名称 = new Array(); // 创建一个空数组
      let 变量名称 = new Array(data1, data2, ...); // 创建一个带数据的数组
      
    2. 通过字面量创建数组 (开发中数组一般就是用的字面量方式创建)

      let 变量名称 = []; // 创建一个空数组
      let 变量名称 = [data1, data2, ...]; //  创建一个带数据的数组
      

数组的遍历和解构赋值

遍历

数组的遍历就是依次取出数组中存储的所有数据

for(let i = 0; i < arr.length; i++){
    console.log(arr[i]);
}
解构赋值

解构赋值是ES6中新增的一种赋值方式

// ES6 以前
let arr = [1, 3, 5];
let a = arr[0];
let b = arr[1];
let c = arr[2];
// ES6 新方式
let [a, b, c] = arr;
console.log("a = " + a);
console.log("b = " + b);
console.log("c = " + c);

注意点:

  1. 在数组的解构赋值中, 赋值号左边的格式必须和赋值号右边的格式一模一样, 才能完全解构

  2. 在数组的解构赋值中, 左边的个数可以和右边的个数不一样, 左边少会丢失, 右边少左边空的值就是 undefined

  3. 在数组的解构赋值中, 我们可以给左边指定默认值, 右边少时左边会有默认值

    let [a, b = 666, c = 888] = [1];
    
  4. 在数组的解构赋值中, 如果左边坑位有对应的右边值, 那么默认值会被覆盖

  5. 在数组的解构赋值中, 还可以使用 ES6 中新增的扩展运算符来打包剩余的数据

  6. 在数组的解构赋值中, 如果使用了扩展运算符, 那么扩展运算符只能写在最后

补充:

ES6中新增的扩展运算符: ...

// let [a, b] = [1, 3, 5];
let [a, ...b] = [1, 3, 5];
console.log("a = " + a);
console.log(b);

数组的增删改查

增 push unshift

需求: 要求在数组最后添加一条数据 (增) push

let arr = ["a", "b", "c"];
arr[3] = "d";
console.log(arr);
// push方法可以在数组的最后新增一条数据, 并且会将新增内容之后数组当前的长度返回给我们
let arr = ["a", "b", "c"];
let res = arr.push("d");
console.log(res);
console.log(arr);

需求: 要求在数组最后添加两条数据 (增)

// 菜鸟行为
let arr = ["a", "b", "c"];
arr.push("d");
arr.push("e");
console.log(arr);
// 数组的 push 方法可以接收 1 个或多个参数
let arr = ["a", "b", "c"];
arr.push("d", "e");
console.log(arr);

需求: 要求在数组最前面添加一条数据 (增) unshift

let arr = ["a", "b", "c"];
// arr[-1] = "m"; //  ["a", "b", "c", -1: "m"]
// unshift方法和push方法一样, 会将新增内容之后当前数组的长度返回给我们
let res = arr.unshift("m");
console.log(res);
console.log(arr);

需求: 要求在数组最前面添加两条数据 (增)

// 菜鸟行为
let arr = ["a", "b", "c"];
arr.unshift("m");
arr.unshift("w");
console.log(arr);
// unshift 方法和 push 方法一样, 可以接收1个或多个参数
let arr = ["a", "b", "c"];
arr.unshift("m", "w");
console.log(arr);
删 pop shift splice

需求: 要求删除数组最后一条数据 (删) 用 pop

 // 数组的 pop 方法可以删除数组中的最后一条数据, 并且将删除的数据返回给我们
let arr = ["a", "b", "c"];
let res = arr.pop();
console.log(res);
console.log(arr);

需求: 要求删除数组最前面一条数据 (删) 用 shift

// 数组的 shift 方法可以删除数组中的最前面一条数据, 并且将删除的数据返回给我们
let arr = ["a", "b", "c"];
let res = arr.shift();
console.log(res);
console.log(arr);

需求: 要求删除数组中索引为1的数据 (删)

// 以下代码的含义: 从索引为1的元素开始删除1条数据
/*
参数1: 从什么位置开始
参数2: 需要删除多少个元素
*/
let arr = ["a", "b", "c"];
arr.splice(1, 1);
console.log(arr);

需求: 要求删除数组中除了第0条以外的所有数据 (删)

let arr = ["a", "b", "c"];
arr.splice(1); // 从 1 开始直至结束
console.log(arr);
改 splice

需求: 将索引为1的数据修改为m (改)

 let arr = ["a", "b", "c"];
arr[1] = "m";
console.log(arr);

需求: 将索引为1的数据修改为d, 索引为2的修改为e (改) splice

 let arr = ["a", "b", "c"];
arr[1] = "d";
arr[2] = "e";
console.log(arr);
// 用 .splice()
/*
参数1: 从什么位置开始
参数2: 需要替换多少个元素
参数3开始: 新的内容
*/
arr.splice(1, 2, "d", "e");
console.log(arr);

需求: 获取数组中索引为1的那个数据 (查, 易过食碗水)

 let arr = ["a", "b", "c"];
console.log(arr[1]);

数组的常用方法

toString join concat ... splice reverse (这行的会改变原有数组, 比较特殊) indexOf lastIndexOf includes

注意点:

  • 有的方法第二个参数指的是截取的长度比如 splice (还有字符串方法 substr <这个不改变原数组嗷, 和 splice 不同>)
  • 有的方法第二个参数指的是数组索引比如 slice (这种是左闭右开) (还有字符串方法 substring)
  • 不要猜, 用到就查文档就最稳
  1. 清空数组 let arr = [1, 2, 3, 4, 5];

    arr = []
    
    arr.length = 0;
    
    arr.splice(0); 
    
    arr.splice(0, arr.length) 
    
  2. 如何将数组转换为字符串

    let str = arr.toString();
    console.log(str);
    console.log(typeof str);
    
  3. 将数组转换成指定格式字符串

    // join方法默认情况下如果没有传递参数, 就是调用toString();
    // join方法如果传递了参数, 就会将传递的参数作为	元素和元素的连接符号
    let str =  arr.join("+");
    console.log(str);
    console.log(typeof str);
    
  4. 将两个数组拼接为一个数组 concat

    let arr1 = [1, 3, 5];
    let arr2 = [2, 4, 6];
    // 注意点: 数组不能够使用加号进行拼接, 如果使用加号进行拼接会先转换成字符串再拼接
    // let res = arr1 + arr2; // 1,3,52,4,6 
    let res = arr1.concat(arr2);
    console.log(res);
    
    // 注意点: 不会修改原有的数组, 会生成一个新的数组返回给我们
    console.log(arr1);
    console.log(arr2);
    

    扩展运算符

    let arr1 = [1, 3, 5];
    let arr2 = [2, 4, 6];
    /*
    注意点:
    扩展运算符在解构赋值中(等号的左边)表示将剩余的数据打包成一个新的数组
    扩展运算符在等号右边, 那么表示将数组中所有的数据解开, 放到所在的位置
    */
    let res = [...arr1, ...arr2]; // let res = [1, 3, 5, 2, 4, 6];
    console.log(res);
    console.log(typeof res);
    
    // 注意点: 不会修改原有的数组, 会生成一个新的数组返回给我们
    console.log(arr1);
    console.log(arr2);
    
  5. 对数组中的内容进行反转

    let arr = [1, 2, 3, 4, 5];
    let res = arr.reverse();
    console.log(res);
    // 注意点: 会修改原有的数组
    console.log(arr);
    
  6. 截取数组中指定范围内容

    splice, 修改原数组, 返回截取的部分

    const months = ['Jan', 'March', 'April', 'June'];
    months.splice(1, 0, 'Feb');
    // inserts at index 1
    console.log(months);
    // expected output: Array ["Jan", "Feb", "March", "April", "June"]
    
    months.splice(4, 1, 'May');
    // replaces 1 element at index 4
    console.log(months);
    // expected output: Array ["Jan", "Feb", "March", "April", "May"]
    
  7. 查找元素在数组中的位置

    let arr = [1, 2, 3, 4, 5, 3];
    /*
    indexOf方法:
    如果找到了指定的元素, 就会返回元素对应的位置
    如果没有找到指定的元素, 就会返回-1
    默认是从左至右的查找, 一旦找到就会立即停止查找
    */
    let res1 = arr.indexOf(3);
    console.log(res1); // 2
    let res2 = arr.indexOf(6);
    console.log(res2); // -1
    
    /*
    参数1: 需要查找的元素
    参数2: 从什么位置开始查找
    返回值: 仍是元素在数组中对应位置
    */
    let arr = [1, 2, 3, 4, 5, 3];
    let res = arr.indexOf(3, 4);
    console.log(res)
    
    /*
    注意点:
    lastIndexOf方法默认是从右至左的查找, 一旦找到就会立即停止查找
    返回值: 仍是元素在数组中对应位置
    */
    let arr = [1, 2, 3, 4, 5, 3];
    let res = arr.lastIndexOf(3);
    console.log(res);
    
  8. 判断数组中是否包含某个元素

    // 通过 indexOf 或 lastIndexOf 的结果, 判断是否是 -1 即可
    let arr = [1, 2, 3, 4, 5];
    // let res = arr.indexOf(8); // -1
    let res = arr.lastIndexOf(8); // -1
    
    // ES6 中新增了 includes 方法
    let arr = [1, 2, 3, 4, 5];
    let res = arr.includes(4);
    console.log(res); // false
    

二维数组

  1. 什么是二维数组? 二维数组就是数组的每一个元素又是一个数组, 我们就称之为二维数组

    let arr = [[1, 3], [2, 4]];
    
  2. 如何操作二维数组?

    1. 如何从二维数组中获取数据?
      • 数组名称[二维数组索引]; // 得到一个一维数组
      • 数组名称[二维数组索引][一维数组索引]; // 得到一维数组中的元素
    2. 如何往二维数组中存储数据?
      • 数组名称[二维数组索引] = 一维数组;
      • 数组名称[二维数组索引][一维数组索引] = 值;
  3. 遍历二维数组

    let arr = [[1, 3], [2, 4]];
    for(let i = 0; i < arr.length; i++){
        let subArray = arr[i];
        // console.log(subArray);
        for(let j = 0; j < subArray.length; j++){
            console.log(subArray[j]);	
        }
    }