push和pop用于操作数组末尾。
const arr = [1, 2, 3];
// 添加元素到末尾
arr.push(4); // 返回新长度4
console.log(arr); // [1, 2, 3, 4]
// 添加多个元素
arr.push(5, 6, 7); // 返回新长度7
console.log(arr); // [1, 2, 3, 4, 5, 6, 7]
// 合并数组
const arr2 = [8, 9];
arr.push(...arr2);
console.log(arr); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
const arr = [1, 2, 3];
// 移除末尾元素
const last = arr.pop(); // 返回3
console.log(arr); // [1, 2]
// 空数组返回undefined
const empty = [];
console.log(empty.pop()); // undefined
// 实现栈
const stack = [];
stack.push(1);
stack.push(2);
stack.push(3);
console.log(stack.pop()); // 3
console.log(stack.pop()); // 2
shift和unshift用于操作数组开头。
const arr = [3, 4, 5];
// 添加元素到开头
arr.unshift(1, 2); // 返回新长度5
console.log(arr); // [1, 2, 3, 4, 5]
const arr = [1, 2, 3];
// 移除开头元素
const first = arr.shift(); // 返回1
console.log(arr); // [2, 3]
// push/pop比shift/unshift快
// 因为shift/unshift需要移动所有元素
// 大量操作时注意性能
const arr = [];
for (let i = 0; i < 100000; i++) {
arr.push(i); // 快
}
for (let i = 0; i < 100000; i++) {
arr.unshift(i); // 慢
}
slice和splice用于截取和修改数组。
const arr = [1, 2, 3, 4, 5];
// slice(start, end):返回新数组,不修改原数组
arr.slice(1, 3); // [2, 3]
arr.slice(2); // [3, 4, 5]
arr.slice(-2); // [4, 5]
arr.slice(1, -1); // [2, 3, 4]
arr.slice(); // [1, 2, 3, 4, 5](浅拷贝)
console.log(arr); // [1, 2, 3, 4, 5](原数组不变)
const arr = [1, 2, 3, 4, 5];
// splice(start, deleteCount, ...items):修改原数组
// 删除元素
arr.splice(2, 1); // 返回[3]
console.log(arr); // [1, 2, 4, 5]
// 插入元素
arr.splice(2, 0, 3); // 返回[]
console.log(arr); // [1, 2, 3, 4, 5]
// 替换元素
arr.splice(2, 1, "三"); // 返回[3]
console.log(arr); // [1, 2, "三", 4, 5]
// 删除多个并插入
arr.splice(1, 2, "二", "三"); // 返回[2, "三"]
console.log(arr); // [1, "二", "三", 4, 5]
| 特性 | slice | splice | 东巴文建议 |
|---|---|---|---|
| 修改原数组 | 否 | 是 | - |
| 返回值 | 新数组 | 删除的元素 | - |
| 用途 | 复制/截取 | 删除/插入/替换 | - |
concat用于合并数组。
const arr1 = [1, 2];
const arr2 = [3, 4];
// 合并数组
const merged = arr1.concat(arr2); // [1, 2, 3, 4]
console.log(arr1); // [1, 2](原数组不变)
// 合并多个数组
const arr3 = [5, 6];
const merged2 = arr1.concat(arr2, arr3); // [1, 2, 3, 4, 5, 6]
// 合并值
const merged3 = arr1.concat(3, 4, [5, 6]); // [1, 2, 3, 4, 5, 6]
const arr = [{ name: "东巴文" }];
const copied = arr.concat();
copied[0].name = "JavaScript";
console.log(arr[0].name); // "JavaScript"(浅拷贝)
const arr1 = [1, 2];
const arr2 = [3, 4];
// concat
const merged1 = arr1.concat(arr2);
// 展开运算符
const merged2 = [...arr1, ...arr2];
join将数组转换为字符串。
const arr = ["东", "巴", "文"];
arr.join(); // "东,巴,文"(默认逗号)
arr.join(""); // "东巴文"
arr.join("-"); // "东-巴-文"
arr.join(" "); // "东 巴 文"
// URL路径
const path = ["api", "v1", "users"];
const url = "/" + path.join("/"); // "/api/v1/users"
// CSS类名
const classes = ["btn", "btn-primary", "active"];
const className = classes.join(" "); // "btn btn-primary active"
// CSV格式
const data = [
["name", "age", "city"],
["东巴文", "1", "北京"],
["张三", "20", "上海"]
];
const csv = data.map(row => row.join(",")).join("\n");
const str = "东-巴-文";
const arr = str.split("-"); // ["东", "巴", "文"]
const str2 = arr.join("-"); // "东-巴-文"
reverse反转数组。
const arr = [1, 2, 3, 4, 5];
arr.reverse(); // [5, 4, 3, 2, 1]
console.log(arr); // [5, 4, 3, 2, 1](修改原数组)
const arr = [1, 2, 3, 4, 5];
// 使用slice先复制
const reversed = arr.slice().reverse();
console.log(arr); // [1, 2, 3, 4, 5]
console.log(reversed); // [5, 4, 3, 2, 1]
// 使用展开运算符
const reversed2 = [...arr].reverse();
const str = "东巴文";
const reversed = str.split("").reverse().join("");
console.log(reversed); // "文巴东"
sort对数组进行排序。
// 默认按字符串Unicode码点排序
const arr = [10, 2, 30, 4, 100];
arr.sort(); // [10, 100, 2, 30, 4](字符串排序)
const names = ["东巴文", "JavaScript", "HTML"];
names.sort(); // ["HTML", "JavaScript", "东巴文"]
// 数字升序
const numbers = [10, 2, 30, 4, 100];
numbers.sort((a, b) => a - b); // [2, 4, 10, 30, 100]
// 数字降序
numbers.sort((a, b) => b - a); // [100, 30, 10, 4, 2]
// 对象数组排序
const users = [
{ name: "东巴文", age: 1 },
{ name: "张三", age: 20 },
{ name: "李四", age: 15 }
];
users.sort((a, b) => a.age - b.age);
// [{ name: "东巴文", age: 1 }, { name: "李四", age: 15 }, { name: "张三", age: 20 }]
// 比较函数返回值
// 负数:a排在b前面
// 正数:b排在a前面
// 0:顺序不变
arr.sort((a, b) => {
if (a < b) return -1; // a在前
if (a > b) return 1; // b在前
return 0; // 相等
});
// 简写
arr.sort((a, b) => a - b); // 升序
arr.sort((a, b) => b - a); // 降序
const names = ["东巴文", "abc", "ABC", "123"];
// 区分大小写
names.sort(); // ["123", "ABC", "abc", "东巴文"]
// 不区分大小写
names.sort((a, b) => a.localeCompare(b, "zh-CN"));
// 中文排序
const chinese = ["张三", "李四", "王五"];
chinese.sort((a, b) => a.localeCompare(b, "zh-CN"));
查找元素在数组中的位置。
const arr = [1, 2, 3, 2, 1];
arr.indexOf(2); // 1(第一个匹配)
arr.indexOf(2, 2); // 3(从索引2开始查找)
arr.indexOf(4); // -1(未找到)
const arr = [1, 2, 3, 2, 1];
arr.lastIndexOf(2); // 3(最后一个匹配)
arr.lastIndexOf(2, 2); // 1(从索引2向前查找)
arr.lastIndexOf(4); // -1
const arr = [1, NaN, 2];
arr.indexOf(NaN); // -1(indexOf无法找到NaN)
// 使用includes
arr.includes(NaN); // true
// 使用findIndex
arr.findIndex(Number.isNaN); // 1
检查数组是否包含某个元素。
const arr = [1, 2, 3, NaN];
arr.includes(2); // true
arr.includes(4); // false
arr.includes(NaN); // true(可以检测NaN)
// 从指定位置开始
arr.includes(1, 1); // false(从索引1开始)
arr.includes(1, -3); // true(从倒数第3个开始)
const arr = [1, 2, 3, NaN];
// indexOf
arr.indexOf(2) !== -1; // true
arr.indexOf(NaN) !== -1; // false(无法检测NaN)
// includes
arr.includes(2); // true
arr.includes(NaN); // true
// 东巴文建议:检查存在性用includes
查找满足条件的元素。
const users = [
{ id: 1, name: "东巴文" },
{ id: 2, name: "张三" },
{ id: 3, name: "李四" }
];
// 返回第一个满足条件的元素
const found = users.find(user => user.id === 2);
console.log(found); // { id: 2, name: "张三" }
// 未找到返回undefined
const notFound = users.find(user => user.id === 99);
console.log(notFound); // undefined
const users = [
{ id: 1, name: "东巴文" },
{ id: 2, name: "张三" },
{ id: 3, name: "李四" }
];
// 返回第一个满足条件的索引
const index = users.findIndex(user => user.id === 2);
console.log(index); // 1
// 未找到返回-1
const notFound = users.findIndex(user => user.id === 99);
console.log(notFound); // -1
const arr = [1, 2, 3, 4, 5];
// 从后往前查找
arr.findLast(x => x > 2); // 5
arr.findLastIndex(x => x > 2); // 4
检查数组元素是否满足条件。
const arr = [2, 4, 6, 8, 10];
// 所有元素都满足条件
arr.every(x => x > 0); // true
arr.every(x => x > 5); // false
// 空数组返回true
[].every(x => x > 0); // true
const arr = [1, 2, 3, 4, 5];
// 至少一个元素满足条件
arr.some(x => x > 3); // true
arr.some(x => x > 10); // false
// 空数组返回false
[].some(x => x > 0); // false
// 验证所有字段
const form = {
name: "东巴文",
email: "test@example.com",
age: 1
};
const isValid = Object.values(form).every(v => v);
// 检查权限
const permissions = ["read", "write"];
const canDelete = permissions.some(p => p === "delete");
过滤数组元素。
const numbers = [1, 2, 3, 4, 5, 6];
// 过滤偶数
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4, 6]
// 过滤大于3的数
const big = numbers.filter(n => n > 3);
console.log(big); // [4, 5, 6]
const users = [
{ name: "东巴文", age: 1, active: true },
{ name: "张三", age: 20, active: false },
{ name: "李四", age: 15, active: true }
];
// 过滤活跃用户
const activeUsers = users.filter(u => u.active);
// 过滤成年用户
const adults = users.filter(u => u.age >= 18);
const arr = [0, 1, false, 2, "", 3, null, undefined, NaN];
// 去除假值
const truthy = arr.filter(Boolean);
console.log(truthy); // [1, 2, 3]
映射数组元素。
const numbers = [1, 2, 3, 4, 5];
// 每个元素乘以2
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// 每个元素平方
const squared = numbers.map(n => n * n);
console.log(squared); // [1, 4, 9, 16, 25]
const users = [
{ id: 1, name: "东巴文" },
{ id: 2, name: "张三" }
];
// 提取属性
const names = users.map(u => u.name); // ["东巴文", "张三"]
// 转换结构
const formatted = users.map(u => ({
...u,
displayName: `用户: ${u.name}`
}));
const numbers = [1, 2, 3, 4, 5, 6];
const result = numbers
.filter(n => n % 2 === 0) // [2, 4, 6]
.map(n => n * 2); // [4, 8, 12]
console.log(result); // [4, 8, 12]
归约数组为单个值。
const numbers = [1, 2, 3, 4, 5];
// 求和
const sum = numbers.reduce((acc, cur) => acc + cur, 0);
console.log(sum); // 15
// 求积
const product = numbers.reduce((acc, cur) => acc * cur, 1);
console.log(product); // 120
arr.reduce((accumulator, currentValue, index, array) => {
// accumulator: 累加器
// currentValue: 当前值
// index: 当前索引
// array: 原数组
}, initialValue);
const numbers = [1, 2, 3, 4, 5];
// 最大值
const max = numbers.reduce((a, b) => a > b ? a : b);
// 最小值
const min = numbers.reduce((a, b) => a < b ? a : b);
// 计数
const words = ["东", "巴", "文", "东", "巴"];
const count = words.reduce((acc, word) => {
acc[word] = (acc[word] || 0) + 1;
return acc;
}, {});
// { 东: 2, 巴: 2, 文: 1 }
// 数组扁平化
const nested = [[1, 2], [3, 4], [5]];
const flat = nested.reduce((acc, arr) => acc.concat(arr), []);
// [1, 2, 3, 4, 5]
const users = [
{ name: "东巴文", score: 85 },
{ name: "张三", score: 60 },
{ name: "李四", score: 90 }
];
// 总分
const totalScore = users.reduce((sum, user) => sum + user.score, 0);
// 分组
const grouped = users.reduce((acc, user) => {
const key = user.score >= 80 ? "pass" : "fail";
if (!acc[key]) acc[key] = [];
acc[key].push(user);
return acc;
}, {});
遍历数组元素。
const arr = ["东", "巴", "文"];
arr.forEach((item, index, array) => {
console.log(index, item);
});
// 0 "东"
// 1 "巴"
// 2 "文"
const arr = [1, 2, 3];
// forEach:无法中断
arr.forEach(x => {
if (x === 2) return; // 只是跳过当前迭代
console.log(x);
});
// for...of:可以中断
for (const x of arr) {
if (x === 2) break; // 可以中断
console.log(x);
}
// forEach不返回值
const result = [1, 2, 3].forEach(x => x * 2);
console.log(result); // undefined
// 不会处理空位
[1, , 3].forEach(x => console.log(x)); // 1, 3
填充数组元素。
const arr = [1, 2, 3, 4, 5];
// 全部填充
arr.fill(0); // [0, 0, 0, 0, 0]
// 指定范围
const arr2 = [1, 2, 3, 4, 5];
arr2.fill(0, 2); // [1, 2, 0, 0, 0](从索引2开始)
arr2.fill(0, 1, 3); // [1, 0, 0, 4, 5](索引1到3,不含3)
// 创建指定长度的数组并填充
const arr = new Array(5).fill(0); // [0, 0, 0, 0, 0]
// 注意对象填充是引用
const arr2 = new Array(3).fill({});
arr2[0].name = "东巴文";
console.log(arr2); // [{ name: "东巴文" }, { name: "东巴文" }, { name: "东巴文" }]
// 使用from避免引用问题
const arr3 = Array.from({ length: 3 }, () => ({}));
在数组内部复制元素。
const arr = [1, 2, 3, 4, 5];
// 从索引0复制到索引3
arr.copyWithin(3); // [1, 2, 3, 1, 2]
const arr2 = [1, 2, 3, 4, 5];
// 从索引0到2复制到索引3
arr2.copyWithin(3, 0, 2); // [1, 2, 3, 1, 2]
const arr3 = [1, 2, 3, 4, 5];
// 从索引-2复制到索引0
arr3.copyWithin(0, -2); // [4, 5, 3, 4, 5]
扁平化数组。
const nested = [1, [2, 3], [4, [5, 6]]];
nested.flat(); // [1, 2, 3, 4, [5, 6]](默认深度1)
nested.flat(2); // [1, 2, 3, 4, 5, 6]
nested.flat(Infinity); // 完全扁平化
const arr = [1, 2, 3];
// map + flat
arr.flatMap(x => [x, x * 2]);
// [1, 2, 2, 4, 3, 6]
// 等价于
arr.map(x => [x, x * 2]).flat();
// 分割单词
const sentences = ["Hello World", "东巴文 JavaScript"];
const words = sentences.flatMap(s => s.split(" "));
// ["Hello", "World", "东巴文", "JavaScript"]
// 过滤并映射
const numbers = [1, 2, 3, 4, 5];
const result = numbers.flatMap(x =>
x % 2 === 0 ? [x * 2] : []
);
// [4, 8]
掌握了数组方法后,让我们继续学习:
东巴文(db-w.cn) - 让编程学习更简单
🔧 东巴文寄语:数组方法是JavaScript中最常用的API,掌握push/pop、slice/splice、map/filter/reduce等方法,能让你高效地处理各种数据操作。在 db-w.cn,我们帮你精通每一个方法!