---
author: QinIndexCode
tags: JavaScript, 数据结构, 性能优化
---

## 2025-12-24 JS索引数据
JavaScript 中快速索引数据的方法

在 JavaScript 里，想根据一个“键”快速拿到对应的值，通常有两个选择：普通对象（Object）或者 Map。两者底层都依赖哈希表（hash table），查找、插入和删除的平均时间复杂度都是 O(1)，区别主要在键的类型和使用体验上。

### 1. 使用普通对象（Object）

对象是最常见的索引方式，键只能是字符串或者 Symbol。

```javascript
const data = {
  'key1': 'value1',
  'key2': 'value2',
  'key3': 'value3'
};

// 快速访问
console.log(data['key2']); // 输出: 'value2'
console.log(data.key2);    // 也可以用点语法（键名合法时）
```

优点：
- 语法简单，开箱即用
- 适合键名固定、且都是字符串的场景
- V8 对普通对象有专门优化，访问速度很快

缺点：
- 键会被自动转成字符串（`{ 123: 'num' }` 里的键实际是 `"123"`）
- 对象、数组等复杂类型不能直接当键
- 存在原型链污染的风险，`__proto__` 这类特殊键要小心
- 遍历顺序不完全等于插入顺序，整数形式的键会按数字大小排列

### 2. 使用 Map

Map 是 ES6 引入的键值集合类型，键可以是任意类型——对象、函数、NaN 都可以。

```javascript
const map = new Map();

map.set('key1', 'value1');
map.set('key2', 'value2');
map.set('key3', 'value3');

// 甚至可以用对象作为键
const objKey = { id: 1 };
map.set(objKey, '关联的对象值');

// 快速访问
console.log(map.get('key2'));      // 输出: 'value2'
console.log(map.get(objKey));      // 输出: '关联的对象值'
```

优点：
- 键可以是任意值，没有类型限制
- 严格按插入顺序遍历
- 自带 size 属性和 has()、delete()、clear() 等方法
- 没有原型链，不用担心污染问题

缺点：
- 相比普通对象有一点额外开销，但通常可以忽略
- 写法上稍啰嗦一点

### 3. 两者底层原理：哈希表

普通对象和 Map 在 V8 这类现代引擎里，底层都离不开哈希表。

- 写入时，引擎先算键的哈希值，把值放进对应的槽位；
- 读取时再算一次哈希，直接定位到槽位取值，平均时间复杂度 O(1)。

所谓“快速索引”，快就快在这里。

### 4. 类似数组的索引行为


```javascript
[1, 2, 3, 4, 5][1]  // 输出: 2
```

数组靠整数下标访问：密集数组在引擎里是一块连续内存，按下标直接取值；稀疏数组则会退化成字典式存储。数组适合有序、连续的数据，对象和 Map 适合任意键的映射。

### 5. 何时选哪种？

| 场景                                   | 推荐使用    | 原因                                      |
|----------------------------------------|-------------|-------------------------------------------|
| 键是字符串，数据量不大，追求极简语法   | Object      | 最轻量、性能最好                          |
| 需要用对象/函数等复杂类型作为键        | Map         | Object 会把键转为字符串                   |
| 需要频繁删除键或查询是否存在            | Map         | 提供 has()、delete()、size 等便捷方法     |
| 需要保持插入顺序或可迭代性             | Map         | for...of 遍历顺序固定                     |
| 键可能是数字但不想转为字符串           | Map         | 如 map.set(123, value) 与 '123' 区分开来   |
### 小结

快速索引的核心就两类：对象和 Map，底层都是哈希表。键是固定字符串、追求写法简单就用对象；需要复杂类型键、频繁增删，或者在意遍历顺序，就用 Map。
