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(降序).
相关推荐
AAA阿giao1 小时前
深入理解 JavaScript 中的 Symbol:独一无二的“魔法钥匙”
前端·javascript·ecmascript 6
一只乔哇噻1 小时前
java后端工程师+AI大模型进修ing(研一版‖day58)
java·开发语言
晴栀ay1 小时前
JS面向对象:从"猫"的视角看JavaScript的OOP进化史
前端·javascript·面试
lichong9511 小时前
Android 弹出进度条对话框 避免用户点击界面交互
java·前端·javascript
Amy_yang1 小时前
UniApp Vue3 词云组件开发实战:从原理到应用
javascript·vue.js·uni-app
JHC0000001 小时前
47. 全排列 II
开发语言·python·面试
灵犀坠1 小时前
前端知识体系全景:从跨域到性能优化的核心要点解析
前端·javascript·vue.js·性能优化·uni-app·vue
g***86691 小时前
Windows上安装Go并配置环境变量(图文步骤)
开发语言·windows·golang
Drone_xjw1 小时前
【Qt经验】QT软件打包报错 无法定位程序输入点_ZdlPvj于动态链接库 Qt5Sql.dll上
开发语言·qt