Appearance
数组核心 API
数组方法速查表
方法 | 行为特征 | 返回值 | 原数组影响 |
---|---|---|---|
map | 遍历转换 | 新数组 | ❌ 不影响 |
filter | 条件过滤 | 过滤后的新数组 | ❌ 不影响 |
concat | 数组拼接 | 新合并数组 | ❌ 不影响 |
push/pop | 队尾操作 | 操作后数组长度 | ✅ 修改 |
unshift/shift | 队首操作 | 操作后数组长度 | ✅ 修改 |
sort | 排序/反转 | 排序后的数组 | ✅ 修改 |
slice | 区间截取 | 新子数组 | ❌ 不影响 |
splice | 删除/插入/替换 | 被删元素数组 | ✅ 修改 |
join | 数组转字符串 | 连接后的字符串 | ❌ 不影响 |
split | 字符串转数组 | 切割后的新数组 | ❌ 不影响 |
forEach | 遍历执行 | undefined | ❌ 不影响 |
some | 存在性验证 | boolean | ❌ 不影响 |
every | 全量验证 | boolean | ❌ 不影响 |
indexOf | 元素索引查找 | number (找不到返回-1) | ❌ 不影响 |
includes | 存在性检查 | boolean | ❌ 不影响 |
reduce | 累积计算 | 最终累积值 | ❌ 不影响 |
关键方法深度解析
slice vs splice
javascript
const arr = [1, 2, 3, 4, 5];
// slice 截取子数组(不修改原数组)
const subArr = arr.slice(1, 3); // [2,3]
// splice 删除/插入(修改原数组)
const removed = arr.splice(1, 2, 100, 200);
// 原数组变为 [1,100,200,4,5]
// removed 返回 [2,3]
join & split 转换技巧
javascript
// 数组转字符串
const str = ["a", "b", "c"].join("|"); // "a|b|c"
// 字符串转数组
const arr = str.split("|"); // ["a", "b", "c"]
空元素处理陷阱
javascript
// 创建包含空位的数组
const sparseArr = new Array(3); // [empty × 3]
// 遍历行为差异
sparseArr.map((_, i) => i); // [empty × 3](跳过空位)
Array.from(sparseArr).map((_, i) => i); // [0,1,2](填充undefined)
特殊场景处理
查找方法对比
javascript
const arr = [1, 2, NaN];
console.log(arr.indexOf(NaN)); // -1(无法识别NaN)
console.log(arr.includes(NaN)); // true(使用SameValueZero算法)
类数组对象处理
javascript
// 类数组特征示例
const arrayLike = {
0: "a",
1: "b",
length: 2,
// 手动添加数组方法
push: Array.prototype.push,
};
// 转换方法
const realArray = Array.from(arrayLike); // ["a", "b"]
数组扁平化方案
javascript
// 1. flat方法(推荐)
[1, [2, [3]]].flat(Infinity); // [1,2,3]
// 2. 递归实现
function deepFlatten(arr, result = []) {
arr.forEach((item) =>
Array.isArray(item) ? deepFlatten(item, result) : result.push(item)
);
return result;
}
// 3. toString转换(仅限数字字符串)
const numStrArr = [1, [2, [3]]].toString().split(","); // ["1", "2", "3"]
底层实现原理
includes 方法实现
javascript
Array.prototype.includes = function (searchElement, fromIndex) {
if (this == null) throw new TypeError();
const arr = Object(this);
const len = arr.length >>> 0;
let start = fromIndex ? Number(fromIndex) : 0;
if (isNaN(start)) start = 0;
else if (start < 0) start = Math.max(len + start, 0);
const isNaN = Number.isNaN(searchElement);
for (let i = start; i < len; i++) {
const current = arr[i];
if (current === searchElement || (isNaN && Number.isNaN(current))) {
return true;
}
}
return false;
};
entries 迭代器实现
javascript
Array.prototype.entries = function () {
let index = 0;
const arr = this;
return {
next() {
return index < arr.length
? { value: [index++, arr[index - 1]], done: false }
: { done: true };
},
[Symbol.iterator]() {
return this;
},
};
};
// 使用示例
for (const [idx, val] of [10, 20, 30].entries()) {
console.log(idx, val); // 0 10 → 1 20 → 2 30
}
常见陷阱解析
自动分号插入问题
javascript
// 数组字面量换行导致的问题
let a = [1, 2, 3][2]; // 等价于 [1,2,3][2] → 返回3
// 对象字面量换行问题
let b = { x: 10 }["x"]; // 等价于 {x:10}["x"] → 返回10
数组长度异常场景
javascript
// 稀疏数组创建对比
const arr1 = [1]; // length:1
const arr2 = [1, ,]; // length:2(含空位)
const arr3 = new Array("10"); // length:1(元素为"10")
const arr4 = new Array(10); // length:10(全空位)
push 方法源码模拟
javascript
// 简化版push实现
function push(element) {
this[this.length] = element;
return this.length++;
}
// 使用示例
const obj = { 0: "a", length: 1 };
obj.push("b"); // obj变为 {0:'a', 1:'b', length:2}