JavaScript基础(七):数组

一.核心概念

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

二.数组的创建

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

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

// 空数组
const arr1 = [];

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

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

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

灵活但需注意特殊情况:

// 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():

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

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

II.Array.from():

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

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):

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 可扩容 / 缩容(缩容会删除超出长度的元素)

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 表示不删除)

示例:

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()过滤元素(保留满足条件的),返回新数组否(纯函数)

示例:

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)累加 / 归约,将数组转为单个值最终累加结果

示例:

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 排序,需自定义比较函数)

示例:

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:结束索引(可选,默认到数组末尾)

示例:

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)扁平化后的新数组

示例:

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.数组去重

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.数组求和 / 求平均值

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.多维数组扁平化

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

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

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(降序).
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值