6JavaScript: The Good Parts

数组

数组的智慧

数组字面量数组方法长度属性稀疏数组

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第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 方法为什么需要比较函数?

如何高效地遍历数组?

数组和类数组对象有什么区别?


6/9数组
0%