视频加载失败

JavaScript数组

3870 字
19 分钟
JavaScript数组

数组简介和定义#

什么是数组

数组(Array)是 JavaScript 中的一种引用数据类型,用于在一个变量中存储多个数据。

数组具有以下特点:

  • 可以存储多个数据,且数据类型可以不同。
  • 数组中的每个元素都有对应的下标(索引)。
  • 下标从 0 开始。
  • 数组长度可以动态变化。

数组的定义方法

数组的定义方法有几种:

//使用 [] 定义数组,是最常用、最推荐的方式。
var arr = ['A', 'B','C','D'];
//使用 new Array() 创建数组
var arr = new Array('A','B', 'C', 'D');
//下面的代码表示定义一个长度为4的数组,但是这4项都是 undefined
var arr = new Array(4);
//根据传入的参数创建数组,解决了 Array() 传入单个数字时的歧义。
const arr2 = Array.of(10, 20, 30); // [10, 20, 30]

访问数组项

通过数组的下标访问元素,语法:

//数组名[下标]
const fruits = ["苹果", "香蕉", "橘子"];
console.log(fruits[0]); // 苹果
console.log(fruits[1]); // 香蕉
console.log(fruits[2]); // 橘子

下标越界

当访问的下标不存在时,JavaScript 通常返回 undefined,不会直接报错。

const arr = [10, 20, 30];
console.log(arr[3]); // undefined
console.log(arr[10]); // undefined
console.log(arr[-1]); // undefined

注意:对数组本身访问不存在的下标通常不会报错,但继续访问 undefined 的属性可能报错。

数组的长度

使用 length 属性获取数组长度。

const arr = [10, 20, 30, 40];
console.log(arr.length); // 4
// 获取最后一个元素
console.log(arr[arr.length - 1]); // 40

length 可以修改:

const arr = [10, 20, 30];
arr.length = 2;
console.log(arr); // [10, 20]
arr.length = 5; // 长度为5,后面增加3个空槽位

注意:数组长度不一定等于实际存在的元素数量,因为 JavaScript 允许稀疏数组。

更改数组项

直接通过下标修改数组中的元素。

const arr = [10, 20, 30];
arr[1] = 99;
console.log(arr); // [10, 99, 30]

也可以通过新的下标添加元素:

arr[3] = 40;
console.log(arr); // [10, 99, 30, 40]

即使使用 const 定义数组,也可以修改内部元素,因为 const 限制的是变量重新赋值,并不禁止修改数组内容。

数组的遍历

数组遍历,就是依次访问数组中的元素。(在学习ES6的时候,有扩展很多循环语法,基础的记住for和while,数组使用for…of,对象使用for…in,特殊情况除外 )

方法1:for 循环:适合需要操作下标的场景。

const arr = [10, 20, 30];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}

方法2:for…of:适合只需要获取元素值的场景。

const arr = [10, 20, 30];
for (const item of arr) {
console.log(item);
}

方法3:forEach():forEach() 可以同时获取元素值和下标,但不能像普通 for 循环一样通过 break 提前退出。

const arr = [10, 20, 30];
arr.forEach((item, index) => {
console.log(index, item);
});

数组类型的检测#

JavaScript 数组本质上属于对象,因此不能单纯使用 typeof 判断。

const arr = [10, 20, 30];
console.log(typeof arr); // object

常见检测方式:

检测方式示例说明
Array.isArray()Array.isArray(arr)推荐方式
instanceofarr instanceof Array检查原型链,跨执行环境可能不准确
Object.prototype.toString.call()Object.prototype.toString.call(arr)返回 [object Array]

实际开发推荐:

const arr = [1, 2, 3];
console.log(Array.isArray(arr)); // true
console.log(Array.isArray({})); // false
console.log(Array.isArray("abc")); // false

数组的常用方法#

数组提供大量内置方法,主要包括添加、删除、查找、遍历、排序和转换。这里只列举一些常用的,在ES6语法中会再增加一些(slice、splice、split这三个英文非常像,初学很可能弄混,这三个是完全不一样功能的,split是字符串的方法,数组可以通过join转字符串,字符串可以使用split转为数组)

添加与删除:这5个是最基础的,splice是功能最多的,push和pop是开发中最常用的

方法作用是否修改原数组
push()末尾添加元素是
pop()删除末尾元素是
unshift()开头添加元素是
shift()删除开头元素是
splice()添加、删除或替换指定位置元素是

push()方法:(末尾追加)

  • push()方法用来在数组末尾推入新项,参数就是要推入 的项

  • 如果要推入多项,可以用逗号隔开

  • 调用push()方法后,数组会立即改变,不需要赋值

    var arr = [1, 2, 3];
    arr.push(4);
    console.log(arr); // [1, 2, 3, 4]
    arr.push(5, 6);
    console.log(arr); // [1, 2, 3, 4, 5, 6]

pop()方法:(删除末尾)

  • 与push()相反,pop()方法用来删除数组中的最后一项

  • pop()方法不仅会删除数组末项,而且会返回被删除的项

    var arr = [1, 2, 3, 4];
    var item = arr.pop();
    console.log(arr); // [1, 2, 3]
    console.log(item); // 4

unshift()方法:(头部插入)

  • unshift()方法用来在数组头尾插入新项,参数就是要 插入的项

  • 如果要插入多项,可以用逗号隔开

  • 调用unshift()方法后,数组会立即改变,不需要赋值

    var arr = [2, 3, 4];
    arr.unshift(1);
    console.log(arr); // [1, 2, 3, 4]
    arr.unshift(-1, 0);
    console.log(arr); // [-1, 0, 1, 2, 3, 4]

shift()方法:(删除头部)

  • 与unshift()相反,shift()方法用来删除数组中下标为0 的项

  • shift()方法不仅会删除数组末项,而且会返回被删除的项

    var arr = [10, 20, 30];
    var item = arr.shift();
    console.log(arr); // [20, 30]
    console.log(item); // 10

splice()方法

  • splice()方法第一个参数是从哪个下标开始,第二个参数是删除多少个项

    arr.splice(起始下标, 删除个数)
    var arr = ['A','B','C','D','E','F','G'];
    arr.splice(3,2,'X','Y','Z');
    console.log(arr);
    // 下标3开始,连续替换2项;这种说法错误的
    // 准确是:下标3开始,连续删除2项,然后插入新元素
    // [ 'A', 'B', 'C', 'X', 'Y', 'Z','F', 'G']
  • splice()方法可以用于在指定位置插入新项(第二个参数设置0,就没有删除项)

    arr.splice(起始下标, 0, 新元素)
    var arr = [1, 2, 5, 6];
    arr.splice(2, 0, 3, 4);
    console.log(arr); // [1, 2, 3, 4, 5, 6]
  • splice()方法可以用于删除指定项;result返回被删除的项

    arr.splice(起始下标, 删除个数)
    var arr = [10, 20, 30, 40];
    var result = arr.splice(1, 1);
    console.log(arr); // [10, 30, 40]
    console.log(result); // [20]
  • splice()方法会以数组形式返回被删除的项

查找与判断:

方法作用返回值
indexOf()查找元素首次出现的位置下标或 -1
lastIndexOf()查找元素最后出现的位置下标或 -1
includes()判断是否包含元素布尔值
find()查找第一个符合条件的元素元素或 undefined
findIndex()查找第一个符合条件的元素下标下标或 -1
some()是否至少一个元素符合条件布尔值
every()是否所有元素符合条件布尔值

indexOf()方法的功能是搜索数组中的元素,并返回它所 在的位置,如果元素不存在,则返回-1

var arr = ['A', 'B', 'C', 'D'];
console.log(arr.indexOf('B')); // 1
console.log(arr.indexOf('Z')); // -1

includes()方法的功能是判断一个数组是否包含一个指定 的值,返回布尔值

var arr = ['A', 'B', 'C'];
console.log(arr.includes('B')); // true
console.log(arr.includes('Z')); // false

截取、合并与转换

方法作用是否修改原数组
slice()截取数组片段否
concat()合并数组否
join()将数组连接成字符串否
reverse()反转数组是
sort()对数组排序是
flat()展平嵌套数组否

slice()方法:slice()方法用于得到子数组,slice(a, b)截取的子数组从下标为a的项开始,到下标为 b(但不包括下标为b的项)结束

  • 标准写法

    var arr = ['A','B','C','D','E','F'];
    var result = arr.slice(1, 4);
    console.log(result); // ['B','C','D'] 从下标 1 开始;(B)到下标 4 结束(不包含4)所以是:B、C、D
    console.log(arr); // ['A','B','C','D','E','F']
  • slice()如果不提供第二个参数,则表示从指定项开始,提 取所有后续所有项作为子数组

    var arr = ['A','B','C','D','E','F'];
    var result = arr.slice(2);
    console.log(result); // ['C','D','E','F']
  • slice(a, b)方法不会更改原有数组,返回的是截取的数组

    var arr = [1, 2, 3, 4];
    var result = arr.slice(1, 3);
    console.log(result); // [2, 3]
    console.log(arr); // [1, 2, 3, 4] ✔ 原数组不变
  • slice()方法的参数允许为负数,表示数组的倒数第几项

    var arr = ['A','B','C','D','E','F'];
    var result = arr.slice(-3);
    console.log(result); // ['D','E','F']

concat()方法

  • concat()方法可以合并连结多个数组

  • concat()方法不会改变原数组

    var arr1 = [1, 2, 3, 4];
    var arr2 = [5, 6, 7, 8];
    var arr3 = [9, 10, 11];
    var arr = arr1.concat(arr2 , arr3);
    console.log(arr);
    // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

join()方法

  • 数组的join()方法可以使数组转为字符串;字符串的split() 方法可以使字符串转为数组。

  • join()的参数表示以什么字符作为连接符,如果留空则默 认以逗号分隔,如同调用toString()方法

    var arr = ['A', 'B', 'C'];
    var str = arr.join('-');
    console.log(str); // "A-B-C"
  • split()的参数表示以什么字符拆分字符串,一般不能留空

    var str = "A-B-C";
    var arr = str.split('-');
    console.log(arr); // ["A", "B", "C"]

reverse()方法

  • reverse()方法用来将一个数组中的全部项顺序置反

    var arr = ["A","B","C","D"];
    arr.reverse();
    console.log(arr); // ["D","C","B","A"]

遍历相关算法#

  • 题目:求数组中每一项的总和、平均数

    var arr = [10, 20, 30, 40, 50];
    var sum = 0;
    for (var i = 0; i < arr.length; i++) {
    sum += arr[i];
    }
    var avg = sum / arr.length;
    console.log("总和:" + sum);
    console.log("平均数:" + avg);
    var arr = [10, 20, 30, 40, 50];
    var sum = arr.reduce(function (acc, cur) {
    return acc + cur;
    }, 0);
    var avg = sum / arr.length;
    console.log(sum, avg);
  • 题目:求数组项的最大值和最小值

    var arr = [12, 5, 78, 23, 9, 100, 34];
    // 假设第一个是最大值和最小值
    var max = arr[0];
    var min = arr[0];
    for (var i = 1; i < arr.length; i++) {
    if (arr[i] > max) {
    max = arr[i];
    }
    if (arr[i] < min) {
    min = arr[i];
    }
    }
    console.log("最大值:" + max);
    console.log("最小值:" + min);
  • 题目:统计符合条件的元素数量

    const arr = [12, 25, 36, 47, 58];
    let count = 0;
    for (const item of arr) {
    if (item % 2 === 0) {
    count++;
    }
    }
    console.log(count); // 3

数组去重和随机样本#

数组去重

  • 题目:去掉数组中的重复项

  • 思路:准备一个空结果数组,遍历原数组,如果遍历到的项不在结果数组中,则推入结果数组。

    var arr = [1, 2, 3, 2, 4, 1, 5];
    var result = [];
    for (var i = 0; i < arr.length; i++) {
    if (!result.includes(arr[i])) {
    result.push(arr[i]);
    }
    }
    console.log(result);

ES6版本:使用Set,Set 是一种不保存重复值的集合类型,配合展开运算符 ... 可以转换回数组。

const arr = [1, 2, 2, 3, 3, 4];
const result = [...new Set(arr)];
console.log(result); // [1, 2, 3, 4]

filter() + indexOf():原理:只保留每个元素首次出现的位置。这种方式对 NaN 等特殊值不如 Set 合适。

const arr = [1, 2, 2, 3, 3, 4];
const result = arr.filter((item, index) => {
return arr.indexOf(item) === index;
});
console.log(result); // [1, 2, 3, 4]

随机样本

  • 题目:请随机从原数组中取3项

  • 思路:准备一个空结果数组,遍历原数组,随机选择一项 ,推入结果数组,并且将这项删除

    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    var result = [];
    for (var i = 0; i < 3; i++) {
    // 1. 随机下标
    var index = Math.floor(Math.random() * arr.length);
    // 2. 取出该项
    result.push(arr[index]);
    // 3. 删除该项(防止重复)
    arr.splice(index, 1);
    }
    console.log(result);

冒泡排序(重点)#

冒泡排序(Bubble Sort)是一种基础排序算法,**核心思想:相邻两个元素进行比较,如果顺序错误就交换位置。**以升序排序为例,每一轮都把当前未排序部分的最大元素移动到右边。

xxxxxxxxxx var arr = [];for (var i = 0; i < 5; i++) {(function (i) { arr.push(function () { console.log(i); });})(i);//这是立即执行函数,i是当前循环的变量}arr2; // 弹出2js

const arr = [5, 3, 8, 4, 2];
for (let i = 0; i < arr.length - 1; i++) {
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
const temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr); // [2, 3, 4, 5, 8]

代码理解:

代码作用
外层 i 循环控制排序轮数
内层 j 循环比较相邻元素
arr[j] > arr[j + 1]判断是否需要交换
temp临时保存元素,完成交换
arr.length - 1 - i排除已经排好序的末尾部分

实际开发中通常使用 sort() 排序,学习冒泡排序的重点在于掌握双层循环、相邻比较和元素交换。

二维数组#

二维数组可以理解为数组中的元素仍然是数组。

访问二维数组:通过两个下标访问元素:

const arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
//第一个下标表示外层数组的索引,第二个表示内层数组的索引。
console.log(arr[0][0]); // 1
console.log(arr[1][2]); // 6
console.log(arr[2][1]); // 8

遍历二维数组<使用双层循环>:

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

创建二维数组

例如创建一个 3 行 4 列,所有元素为 0 的二维数组:

const arr = Array.from(
{ length: 3 },
() => Array(4).fill(0)
);
console.log(arr);

得到:

[
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
]

注意:不要使用 Array(3).fill(Array(4).fill(0)) 创建需要独立修改每一行的二维数组,因为这种方式会让每一行引用同一个内层数组。

基本类型值和引用类型值#

  • 基本类型:number、boolean、string、undefined、 null
  • 引用类型:array、object、function、regexp…

相等判断时的区别:

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

深克隆和浅克隆(重点)#

  • 浅克隆:只克隆数组的第一层,如果是多维数组,或者数 组中的项是其他引用类型值,则不克隆其他层

    var arr = [1, 2, 3];
    var newArr = [];
    for (var i = 0; i < arr.length; i++) {
    newArr.push(arr[i]);
    }
    arr.push(222);
    console.log(newArr); // [1, 2, 3]
    console.log(arr); // [1, 2, 3,222]
    var arr = [{ a: 1 }, { b: 2 }];
    var newArr = [];
    for (var i = 0; i < arr.length; i++) {
    newArr.push(arr[i]);
    }
    newArr[0].a = 100//改变新数组,旧数组也更着变了
    console.log(newArr); // [ { a: 100 }, { b: 2 } ]
    console.log(arr); // [ { a: 100 }, { b: 2 } ]
  • 深克隆:克隆数组的所有层,要使用递归技术,在后面介绍,但是在现代开发中有一个api可以实现,不用手写递归,那就是structuredClone() ,自 2022 年 3 月起已在主流浏览器中广泛支持,Node.js 从 17.0.0 开始提供该 API。

  • 它支持数组、普通对象、Date、Map、Set 等,也支持循环引用,但有一些限制。

    数据类型是否支持
    普通对象、数组✔
    嵌套对象、二维数组✔
    Date、Map、Set✔
    循环引用✔
    函数❌
    DOM 元素❌
    Proxy 代理对象❌
    自定义类的原型与方法不能完整保留
  • 对象深克隆:

    // 对象深克隆
    const obj1 = {
    name: "张三",
    age: 20,
    hobby: ["篮球", "足球"],
    address: {
    city: "北京"
    }
    };
    const obj2 = structuredClone(obj1);
    obj2.hobby[0] = "羽毛球";
    obj2.address.city = "上海";
    console.log(obj1.hobby); // ["篮球", "足球"]
    console.log(obj1.address.city); // 北京
  • 数组深克隆

    const arr1 = [[1, 2], [3, 4]];
    const arr2 = structuredClone(arr1);
    arr2[0][0] = 99;
    console.log(arr1); // [[1, 2], [3, 4]]
    console.log(arr2); // [[99, 2], [3, 4]]

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

JavaScript数组
https://f.youzi177.cn/posts/2026101902javascript-shu-zu/
作者
小封鸭
发布于
2026-10-19
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
小封鸭
小楼一夜听春雨,深巷明朝卖杏花
公告
欢迎来到我的博客。这里主要记录前端全栈和日常内容
分类
标签
最新动态
站点统计
文章
60
分类
3
标签
12
总字数
107,734
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
EdgeOne Pages
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录