重要分类
- 改变原数组:
splice、reverse、sort、push、pop、shift、unshift、fill- 不改变原数组:
map、filter、slice、concat、join、reduce等
一、ES5 数组方法
1.1 查找与检测
indexOf() - 查找元素索引
语法
array.indexOf(searchElement[, fromIndex])
const list = [1, 2, 3];
list.indexOf(2); // 1
list.indexOf("蛙人"); // -1(不存在)
list.indexOf(2, 2); // -1(从索引2开始查找)Array.isArray() - 检测数组
Array.isArray([1, 2, 3]); // true
Array.isArray("not array"); // false1.2 遍历与转换
map() - 映射数组
回调参数
value- 当前元素值index- 当前索引self- 原数组本身
const list = [1, 2, 3];
const res = list.map((value, index, self) => {
console.log(value); // 1 2 3
console.log(index); // 0 1 2
console.log(self); // [1, 2, 3]
return value * 2;
});
console.log(res); // [2, 4, 6]
console.log(list); // [1, 2, 3](原数组不变)forEach() - 遍历数组
const list = [1, 2, 3];
const res = list.forEach((value, index, self) => {
console.log(value); // 1 2 3
console.log(index); // 0 1 2
console.log(self); // [1, 2, 3]
return 123; // 返回值无效
});
console.log(res); // undefinedforEach 特点
- 返回值总是
undefined- 只读操作,不能中断(使用
break或return无效)- 性能比普通
for循环差
filter() - 过滤数组
const list = [1, 2, 3];
const res = list.filter((item) => item > 1);
console.log(res); // [2, 3]
console.log(list); // [1, 2, 3](原数组不变)reduce() - 累加器
语法
array.reduce(callback[, initialValue])
| 参数 | 说明 |
|---|---|
prev | 初始值或上一次计算结果 |
cur | 当前元素 |
index | 当前索引 |
self | 原数组 |
const list = [1, 2, 3];
// 求和
const sum = list.reduce((prev, cur) => prev + cur, 0);
console.log(sum); // 6
// 求最大值
const max = list.reduce((prev, cur) => Math.max(prev, cur));
console.log(max); // 3
// 数组去重
const arr = [1, 2, 2, 3];
const unique = arr.reduce((prev, cur) => {
return prev.includes(cur) ? prev : [...prev, cur];
}, []);
console.log(unique); // [1, 2, 3]1.3 条件检测
every() - 全部满足
const list = [1, 2, 3];
list.every((item) => item > 0); // true(全部大于0)
list.every((item) => item > 1); // false(不全部大于1)some() - 部分满足
const list = [1, 2, 3];
list.some((item) => item > 2); // true(有元素大于2)
list.some((item) => item > 5); // false(没有元素大于5)1.4 操作与截取
splice() - 删除/替换(改变原数组)
改变原数组
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
| 参数 | 说明 |
|---|---|
start | 开始位置 |
deleteCount | 删除数量(0则不删除) |
items | 要添加的元素 |
let list = [1, 2, 3];
// 删除
list.splice(0, 1); // 删除第0位,删除1位
console.log(list); // [2, 3]
// 替换
list.splice(0, 1, "蛙人"); // 删除第0位,添加"蛙人"
console.log(list); // ["蛙人", 2, 3]
// 插入
list.splice(1, 0, "新元素"); // 不删除,在第1位插入
console.log(list); // ["蛙人", "新元素", 2, 3]slice() - 截取数组(不改变原数组)
const list = [1, 2, 3, 4, 5];
// 从索引1截取到索引3(不包含3)
const res = list.slice(1, 3);
console.log(res); // [2, 3]
console.log(list); // [1, 2, 3, 4, 5]
// 从索引2截取到末尾
const res2 = list.slice(2);
console.log(res2); // [3, 4, 5]
// 截取最后2个
const res3 = list.slice(-2);
console.log(res3); // [4, 5]1.5 修改与排序
reverse() - 反转数组(改变原数组)
let list = [1, 2, 3];
const res = list.reverse();
console.log(res); // [3, 2, 1]
console.log(list); // [3, 2, 1](原数组已改变)sort() - 排序(改变原数组)
排序规则
- 返回值
> 0:b排在a前面- 返回值
< 0:a排在b前面- 返回值
= 0:位置不变
let list = [3, 1, 2];
// 升序
list.sort((a, b) => a - b);
console.log(list); // [1, 2, 3]
// 降序
list.sort((a, b) => b - a);
console.log(list); // [3, 2, 1]
// 对象数组排序
const users = [
{ name: "张三", age: 18 },
{ name: "李四", age: 20 }
];
users.sort((a, b) => a.age - b.age);1.6 添加与删除
push() / pop() - 尾部操作(改变原数组)
let list = [1, 2, 3];
// push:尾部添加,返回新长度
const len = list.push(4);
console.log(len); // 4
console.log(list); // [1, 2, 3, 4]
// pop:尾部删除,返回删除的元素
const item = list.pop();
console.log(item); // 4
console.log(list); // [1, 2, 3]shift() / unshift() - 头部操作(改变原数组)
let list = [1, 2, 3];
// shift:头部删除,返回删除的元素
const item = list.shift();
console.log(item); // 1
console.log(list); // [2, 3]
// unshift:头部添加,返回新长度
const len = list.unshift(0);
console.log(len); // 3
console.log(list); // [0, 2, 3]1.7 转换与合并
join() - 数组转字符串
const list = [1, 2, 3];
list.join("-"); // "1-2-3"
list.join(""); // "123"
// 数组求和
const sum = eval(list.join("+"));
console.log(sum); // 6toString() - 转字符串
const list = [1, 2, 3];
const str = list.toString();
console.log(str); // "1,2,3"concat() - 合并数组
const list = [1, 2, 3];
const res = list.concat([4, 5]);
console.log(res); // [1, 2, 3, 4, 5]
console.log(list); // [1, 2, 3](原数组不变)
// 合并多个数组
const res2 = list.concat([4], [5], 6);
console.log(res2); // [1, 2, 3, 4, 5, 6]ES6 替代方案 使用
展开运算符更简洁:const res = [...list, 4, 5];
二、ES6+ 新增方法
2.1 includes() - 包含检测
const list = [1, 2, 3];
list.includes(2); // true
list.includes("蛙人"); // false
// 支持第二个参数(起始位置)
list.includes(1, 1); // false(从索引1开始查找)includes vs indexOf
includes返回布尔值,语义更清晰includes可以检测NaN,indexOf不能
2.2 find() / findIndex() - 查找元素
find() - 查找元素值
const list = [1, 2, 3];
const found = list.find((item) => item > 1);
console.log(found); // 2(返回第一个满足条件的值)
// 查找对象
const users = [
{ id: 1, name: "张三" },
{ id: 2, name: "李四" }
];
const user = users.find((u) => u.id === 2);
console.log(user); // { id: 2, name: "李四" }findIndex() - 查找元素索引
const list = [1, 2, 3];
const index = list.findIndex((item) => item > 1);
console.log(index); // 1(返回第一个满足条件的索引)2.3 flat() / flatMap() - 扁平化
flat() - 拉平嵌套数组
const list = [1, 2, 3, [4, [5]]];
// 拉平一层
list.flat(); // [1, 2, 3, 4, [5]]
// 拉平两层
list.flat(2); // [1, 2, 3, 4, 5]
// 完全拉平
list.flat(Infinity); // [1, 2, 3, 4, 5]flatMap() - 映射后扁平化
const list = [1, 2, 3];
// 相当于 map + flat(1)
const res = list.flatMap((item) => [item, item * 2]);
console.log(res); // [1, 2, 2, 4, 3, 6]2.4 fill() - 填充数组
改变原数组
let list = [1, 2, 3];
// 全部填充
list.fill(0);
console.log(list); // [0, 0, 0]
// 指定范围填充
list = [1, 2, 3, 4, 5];
list.fill(0, 1, 3); // 从索引1到3(不含3)填充0
console.log(list); // [1, 0, 0, 4, 5]
// 创建并填充
const arr = new Array(3).fill(1);
console.log(arr); // [1, 1, 1]2.5 Array.from() - 转真数组
// 伪数组转真数组
const divs = document.getElementsByTagName("div");
const arr = Array.from(divs);
console.log(arr instanceof Array); // true
// 类似 map 操作
const list = [1, 2, 3];
const doubled = Array.from(list, (x) => x * 2);
console.log(doubled); // [2, 4, 6]
// 从字符串创建数组
const strArr = Array.from("abc");
console.log(strArr); // ['a', 'b', 'c']2.6 Array.of() - 创建数组
Array.of(1); // [1]
Array.of(1, 2, 3); // [1, 2, 3]
// 与 Array() 的区别
Array(3); // [empty × 3](创建长度为3的空数组)
Array.of(3); // [3](创建包含元素3的数组)三、方法速查表
3.1 改变原数组的方法
| 方法 | 说明 | 返回值 |
|---|---|---|
push() | 尾部添加 | 新长度 |
pop() | 尾部删除 | 删除的元素 |
shift() | 头部删除 | 删除的元素 |
unshift() | 头部添加 | 新长度 |
splice() | 删除/替换 | 删除的元素数组 |
sort() | 排序 | 排序后的数组 |
reverse() | 反转 | 反转后的数组 |
fill() | 填充 | 填充后的数组 |
3.2 不改变原数组的方法
| 方法 | 说明 | 返回值 |
|---|---|---|
map() | 映射 | 新数组 |
filter() | 过滤 | 新数组 |
forEach() | 遍历 | undefined |
reduce() | 累加 | 累加结果 |
slice() | 截取 | 新数组 |
concat() | 合并 | 新数组 |
join() | 转字符串 | 字符串 |
indexOf() | 查找索引 | 索引或 -1 |
includes() | 包含检测 | true/false |
find() | 查找元素 | 元素值或 undefined |
findIndex() | 查找索引 | 索引或 -1 |
flat() | 扁平化 | 新数组 |
every() | 全部满足 | true/false |
some() | 部分满足 | true/false |
四、使用建议
最佳实践
- 优先使用不改变原数组的方法,避免副作用
- 链式调用:
map().filter().reduce()- 性能考虑:大数据量时,
for循环比forEach快- 类型判断:使用
Array.isArray()而非instanceof