第6章:数组(Arrays)
一、导读
1.1 本章学习目标
第6章深入讲解 JavaScript 的数组。JavaScript 的数组不是传统意义上的连续内存块,而是特殊的对象。
1.2 为什么第六章如此重要
数组是 JavaScript 中最常用的数据结构之一。理解数组的本质和最佳实践,能帮助你写出更高效的代码。
1.3 核心问题引导
JavaScript 数组的本质是什么?
稀疏数组是什么?有什么影响?
数组方法有哪些陷阱?
如何正确使用 length 属性?
二、核心概念详解
6.1 数组的本质
javascript
// 数组是特殊的对象
var a = ["a", "b", "c"];
// 等价于:
var a = {
"0": "a",
"1": "b",
"2": "c",
length: 3
};
// 数组没有真正的连续内存
// 访问速度和对象属性访问一样6.2 数组方法
javascript
var a = [1, 2, 3, 4, 5];
// 常用方法
a.push(6); // [1,2,3,4,5,6]
a.pop(); // 6, a = [1,2,3,4,5]
a.shift(); // 1, a = [2,3,4,5]
a.unshift(0); // a = [0,1,2,3,4,5]
a.splice(2, 1); // 删除索引2的元素
a.slice(1, 3); // [1,2](不修改原数组)
a.concat([6, 7]); // [0,1,2,3,4,5,6,7]
a.reverse(); // 反转
a.sort(); // 排序(注意:按字符串排序!)
a.sort((a, b) => a - b); // 数字排序
a.indexOf(3); // 查找
a.includes(3); // 是否包含
a.join(", "); // "0, 1, 2, 3, 4, 5"6.3 稀疏数组
javascript
// 稀疏数组:有空洞的数组
var sparse = [];
sparse[0] = "a";
sparse[100] = "b";
sparse.length; // 101
// 索引 1-99 是空的(undefined)
// 稀疏数组的性能问题
// 遍历稀疏数组比密集数组慢
// 因为需要检查每个索引是否存在6.4 length 属性
javascript
// length 总是比最大索引大 1
var a = [1, 2, 3];
a.length; // 3
// 设置 length 可以截断数组
a.length = 2; // a = [1, 2]
// 设置 length 大于当前长度,添加空洞
a.length = 5; // a = [1, 2, empty × 3]
// 清空数组
a.length = 0; // a = []三、实战案例
6.1 数组去重
javascript
// 方法1:使用 Set
function unique(arr) {
return [...new Set(arr)];
}
// 方法2:使用 filter
function unique2(arr) {
return arr.filter((item, index) => arr.indexOf(item) === index);
}
// 方法3:使用 reduce
function unique3(arr) {
return arr.reduce((acc, item) => {
if (!acc.includes(item)) acc.push(item);
return acc;
}, []);
}四、本章小结
JavaScript 数组是特殊的对象,不是连续内存。注意 sort 的默认行为、稀疏数组的性能问题、length 属性的特殊行为。
五、思考与练习
JavaScript 数组和 Java 数组有什么区别?
稀疏数组有什么性能问题?
sort 方法为什么需要比较函数?
如何高效地遍历数组?
数组和类数组对象有什么区别?