JavaScript基础(七):数组

一.核心概念

JavaScript 数组(Array)是有序的复合数据类型,用于存储多个不同类型的值(数字、字符串、对象等),支持动态扩容 / 缩容,且提供了丰富的内置方法,是 JS 中最常用的数据结构之一.

二.数组的创建

1.字面量方式(最推荐)

简洁直观,日常开发首选:

javascript 复制代码
// 空数组
const arr1 = [];

// 存储不同类型的值
const arr2 = [10, 'hello', true, { name: '张三' }, [1, 2, 3]];

// 稀疏数组(不推荐,存在空槽)
const arr3 = [1, , 3]; // 索引1为空

2.构造函数方式(new Array())

灵活但需注意特殊情况:

javascript 复制代码
// 1. 无参数:创建空数组(等同于 [])
const arr4 = new Array();

// 2. 单个数字参数:创建指定长度的空数组(仅初始化长度,无实际元素)
const arr5 = new Array(5); // [empty × 5],长度为5,无真实元素

// 3. 多个参数:创建包含这些元素的数组
const arr6 = new Array(10, 20, 30); // [10, 20, 30]

3.其他创建方式

I.Array.of():

统一处理参数(避免单个数字参数的歧义)

javascript 复制代码
Array.of(5); // [5](不同于 new Array(5))
Array.of(10, 20, 30); // [10, 20, 30](等同于字面量)

II.Array.from():

将类数组 / 可迭代对象(如字符串NodeList)转为数组

javascript 复制代码
Array.from('abc'); // ["a", "b", "c"]
Array.from([1, 2, 3], (item) => item * 2); // [2, 4, 6](支持映射函数)

三.数组的核心特性

  1. 有序性:元素按索引(从 0 开始)排列,可通过索引访问 / 修改
  2. 动态长度:无需预先指定长度,添加 / 删除元素时长度自动变化
  3. 异质性:可存储不同类型的值(数字字符串对象函数等)
  4. 本质是对象:数组的 typeof 结果为 object,但有专门的 Array.isArray() 判断

四.数组的基础操作

1.访问 / 修改元素

通过索引操作(索引越界返回 undefined):

javascript 复制代码
const arr = [10, 20, 30];

// 访问元素
console.log(arr[0]); // 10(第一个元素)
console.log(arr[2]); // 30(第三个元素)
console.log(arr[3]); // undefined(索引越界)

// 修改元素
arr[1] = 200;
console.log(arr); // [10, 200, 30]

// 新增元素(直接赋值,数组长度自动扩容)
arr[3] = 40;
console.log(arr); // [10, 200, 30, 40](长度变为4)

2.数组长度(length)

读取 : arr.length 返回数组元素个数
修改 : 手动设置 length 可扩容 / 缩容(缩容会删除超出长度的元素)

javascript 复制代码
const arr = [10, 20, 30];
console.log(arr.length); // 3

// 缩容:删除索引 ≥2 的元素
arr.length = 2;
console.log(arr); // [10, 20]

// 扩容:新增空槽(不推荐,尽量用 push 等方法)
arr.length = 5;
console.log(arr); // [10, 20, empty × 3]

3.新增元素(常用方法)

方法 功能 原数组是否改变
push(elem) 尾部添加一个 / 多个元素,返回新长度
unshift(elem) 头部添加一个 / 多个元素,返回新长度
splice(index, 0, elem) 任意位置插入元素(0 表示不删除)

示例:

javascript 复制代码
const arr = [10, 20];

// push:尾部新增
arr.push(30, 40);
console.log(arr); // [10, 20, 30, 40]

// unshift:头部新增
arr.unshift(0);
console.log(arr); // [0, 10, 20, 30, 40]

// splice:索引 2 插入 15
arr.splice(2, 0, 15);
console.log(arr); // [0, 10, 15, 20, 30, 40]

4.删除元素(常用方法)

方法 功能 原数组是否改变
pop() 尾部删除一个元素,返回删除的元素
shift() 头部删除一个元素,返回删除的元素
splice(index, num) index 开始删除 num 个元素,返回删除的元素数组
filter() 过滤元素(保留满足条件的),返回新数组 否(纯函数)

示例:

javascript 复制代码
const arr = [0, 10, 15, 20, 30, 40];

// pop:尾部删除
const last = arr.pop();
console.log(last); // 40,arr 变为 [0, 10, 15, 20, 30]

// shift:头部删除
const first = arr.shift();
console.log(first); // 0,arr 变为 [10, 15, 20, 30]

// splice:索引 1 开始删除 2 个元素
const deleted = arr.splice(1, 2);
console.log(deleted); // [15, 20],arr 变为 [10, 30]

// filter:保留大于 15 的元素(原数组不变)
const newArr = arr.filter((item) => item > 15);
console.log(newArr); // [30],arr 仍为 [10, 30]

五.数组的核心内置方法(按用途分类)

1.遍历 / 迭代(不改变原数组)

方法 功能 返回值
forEach((item, index, arr) => {}) 遍历每个元素,无返回值 undefined
map((item) => {}) 遍历并映射元素,返回新数组 映射后的新数组
filter((item) => {}) 过滤元素,保留返回 true 的元素 过滤后的新数组
find((item) => {}) 查找第一个满足条件的元素 找到则返回元素,否则 undefined
findIndex((item) => {}) 查找第一个满足条件的元素索引 找到则返回索引,否则 -1
every((item) => {}) 判断所有元素是否满足条件 true/false(短路求值)
some((item) => {}) 判断是否有至少一个元素满足条件 true/false(短路求值)
reduce((acc, item) => {}, init) 累加 / 归约,将数组转为单个值 最终累加结果

示例:

javascript 复制代码
const arr = [1, 2, 3, 4, 5];

// forEach:遍历
arr.forEach((item, index) => {
console.log(`索引${index}:${item}`); // 依次输出 1-5
});

// map:映射(每个元素 ×2)
const doubleArr = arr.map(item => item \* 2);
console.log(doubleArr); // [2, 4, 6, 8, 10]

// filter:过滤偶数
const evenArr = arr.filter(item => item % 2 === 0);
console.log(evenArr); // [2, 4]

// find:找第一个大于 3 的元素
const found = arr.find(item => item > 3);
console.log(found); // 4

// reduce:求和(init 为 0,acc 是累加器)
const sum = arr.reduce((acc, item) => acc + item, 0);
console.log(sum); // 15

2.排序 / 反转(改变原数组)

reverse():反转数组顺序
sort((a, b) => {}):排序(默认按字符串 Unicode 排序,需自定义比较函数)

示例:

javascript 复制代码
const arr = [3, 1, 4, 1, 5];

// 反转
arr.reverse();
console.log(arr); // [5, 1, 4, 1, 3]

// 排序:默认字符串排序(错误,如 10 会排在 2 前面)
arr.sort();
console.log(arr); // [1, 1, 3, 4, 5](巧合正确,数字排序需自定义)

// 数字升序(a - b)
arr.sort((a, b) => a - b);
console.log(arr); // [1, 1, 3, 4, 5]

// 数字降序(b - a)
arr.sort((a, b) => b - a);
console.log(arr); // [5, 4, 3, 1, 1]

3.数组拼接 / 截取(不改变原数组)

concat(arr1, arr2...):拼接多个数组 / 元素,返回新数组
slice(start, end):截取从 start 到 end(不包含 end)的元素,返回新数组
start:起始索引(负数表示从尾部开始,如 -2 表示倒数第二个)
end:结束索引(可选,默认到数组末尾)

示例:

javascript 复制代码
const arr1 = [1, 2];
const arr2 = [3, 4];

// concat:拼接
const newArr = arr1.concat(arr2, 5);
console.log(newArr); // [1, 2, 3, 4, 5],arr1/arr2 不变

// slice:截取
const arr = [10, 20, 30, 40, 50];
console.log(arr.slice(1, 3)); // [20, 30](索引1-2)
console.log(arr.slice(2)); // [30, 40, 50](索引2到末尾)
console.log(arr.slice(-2)); // [40, 50](倒数第二个到末尾)

4.其他常用方法

方法 功能 返回值 原数组是否改变
includes(elem) 判断数组是否包含指定元素 true/false
indexOf(elem) 查找元素第一次出现的索引 索引 /-1
lastIndexOf(elem) 查找元素最后一次出现的索引 索引 /-1
join(sep) 将数组元素拼接为字符串(sep 为分隔符) 拼接后的字符串
flat(depth) 扁平化数组(depth 为扁平化深度,默认 1) 扁平化后的新数组

示例:

javascript 复制代码
const arr = [1, 2, 3, 2, [4, [5]]];

// includes:是否包含 2
console.log(arr.includes(2)); // true

// indexOf:找 2 第一次出现的索引
console.log(arr.indexOf(2)); // 1

// join:用"-"拼接
console.log(arr.join('-')); // "1-2-3-2-4,5"

// flat:扁平化(depth=2 彻底扁平化)
const flatArr = arr.flat(2);
console.log(flatArr); // [1, 2, 3, 2, 4, 5]

六.常用场景示例

1.数组去重

javascript 复制代码
const arr = [1, 2, 2, 3, 3, 3];
// 方法 1:Set 去重(简洁)
const uniqueArr1 = [...new Set(arr)];
// 方法 2:filter 去重(保留第一个出现的元素)
const uniqueArr2 = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(uniqueArr1); // [1, 2, 3]

2.数组求和 / 求平均值

javascript 复制代码
const arr = [1, 2, 3, 4, 5];
// 求和
const sum = arr.reduce((acc, item) => acc + item, 0);
// 求平均值
const avg = sum / arr.length;
console.log(sum); // 15,avg:3

3.多维数组扁平化

javascript 复制代码
const arr = [1, [2, [3, [4]]]];
// 彻底扁平化(depth=Infinity)
const flatArr = arr.flat(Infinity);
console.log(flatArr); // [1, 2, 3, 4]

4.对象数组排序(按指定字段)

javascript 复制代码
const users = [
  { name: '张三', age: 25 },
  { name: '李四', age: 20 },
  { name: '王五', age: 30 }
];
// 按 age 升序
users.sort((a, b) => a.age - b.age);
console.log(users); // 李四(20)→ 张三(25)→ 王五(30)

七.数组的注意事项

  1. 避免稀疏数组: 空槽(empty)在遍历(如 forEach)时会被跳过,容易引发 bug,尽量用正常元素填充.
  2. 区分 "改变原数组" 和 "返回新数组":
    1. 改原数组: push/pop/shift/unshift/splice/sort/reverse
    2. 返新数组: map/filter/concat/slice/flat/Array.from
  3. typeof 判断数组不准确: typeof [] === "object",需用 Array.isArray(arr) 判断是否为数组.
  4. sort 排序的坑: 默认按字符串排序,数字排序必须传入比较函数 (a, b) => a - b(升序)(a, b) => b - a(降序).
相关推荐
xyq20243 分钟前
Memcached stats items 命令详解
开发语言
非科班Java出身GISer4 分钟前
ArcGIS Maps SDK for JavaScript 5.0 组件化开发指南
javascript·arcgis·components·arcgis js 组件化·arcgis js5.0·arcgis js5.0初始化
Evand J4 分钟前
【MATLAB例程】多传感器协同DOA目标跟踪与EKF滤波,输出动态目标轨迹、轨迹误差对比分析
开发语言·matlab·目标跟踪·滤波·定位·导航
csbysj20205 分钟前
《jEasyUI 自定义分页》
开发语言
初心未改HD6 分钟前
Go语言Context深度解析与工程实践
开发语言·golang
SilentSamsara10 分钟前
Python 内存管理:引用计数、循环垃圾回收与内存泄漏排查
开发语言·vscode·python·青少年编程·pycharm
傻啦嘿哟2 小时前
如何在 Python 中使用 colorama 库来给输出添加颜色
开发语言·python
geovindu3 小时前
go: Visitor Pattern
开发语言·设计模式·golang·访问者模式
宣宣猪的小花园.3 小时前
C语言重难点全解析:内存管理到位运算
c语言·开发语言·单片机
方安乐7 小时前
python之向量、向量和、向量点积
开发语言·python·numpy