TypeScript Map 对象

TypeScript 中的 Map 对象详解

Map 是 ES6 引入的内置集合类型,用于存储键值对(key-value pairs),与普通对象({})的最大区别是:Map 的键可以是任意类型(包括对象、函数、Symbol 等),而普通对象的键会被强制转换为字符串。

TypeScript 为 Map 提供了完整的泛型支持,能在编译时检查键和值的类型,极大提升安全性。

1. 基本声明与泛型

// 声明一个键为 string、值为 number 的 Map
let scoreMap: Map<string, number> = new Map();

// 推荐:类型推断(无需显式注解)
let userMap = new Map<string, User>();  // 键 string,值 User 类型

interface User {
  name: string;
  age: number;
}

let users = new Map<number, User>();     // 键为 number(例如 ID)

常见泛型形式:Map<K, V>

  • K:键的类型(Key)
  • V:值的类型(Value)

2. 常用方法

方法描述示例返回值
set(key, value)添加或更新键值对map.set("alice", 95);Map 本身(可链式调用)
get(key)获取值map.get("alice"); → 95 或 undefinedV | undefined
has(key)检查键是否存在map.has("bob"); → true/falseboolean
delete(key)删除指定键map.delete("alice");boolean(是否删除成功)
clear()清空所有键值对map.clear();void
size获取键值对数量map.size → 3number

示例:

let capital = new Map<string, string>();

capital.set("China", "Beijing");
capital.set("Japan", "Tokyo");
capital.set("France", "Paris");

console.log(capital.get("Japan"));    // "Tokyo"
console.log(capital.has("USA"));       // false
console.log(capital.size);            // 3

capital.delete("France");
capital.clear();

3. 遍历 Map

Map 是可迭代对象,支持多种遍历方式:

let fruitCount = new Map<string, number>([
  ["apple", 5],
  ["banana", 3],
  ["orange", 8]
]);

// 1. 遍历键值对(最常用)
for (const [key, value] of fruitCount) {
  // key 类型 string, value 类型 number
  console.log(`${key}: ${value}`);
}

// 2. 遍历键
for (const key of fruitCount.keys()) {
  console.log(key);  // "apple", "banana", "orange"
}

// 3. 遍历值
for (const value of fruitCount.values()) {
  console.log(value);  // 5, 3, 8
}

// 4. 遍历条目(entries)
for (const entry of fruitCount.entries()) {
  console.log(entry);  // ["apple", 5] 等
}

// 5. forEach
fruitCount.forEach((value, key) => {
  console.log(`${key} 有 ${value} 个`);
});

TS 类型安全:遍历时 keyvalue 的类型自动正确推断。

4. 使用对象作为键(Map 的独特优势)

普通对象 {} 不能用对象作为键(会 toString() 成 “[object Object]”),但 Map 可以:

let obj1 = { id: 1 };
let obj2 = { id: 2 };

let objMap = new Map<object, string>();

objMap.set(obj1, "第一项");
objMap.set(obj2, "第二项");

console.log(objMap.get(obj1));  // "第一项"(引用相同才匹配)
console.log(objMap.get({ id: 1 }));  // undefined(新对象,引用不同)

常用于缓存、DOM 节点关联数据等场景。

5. 初始化 Map(构造函数支持可迭代对象)

// 从数组初始化
let pairs: [string, number][] = [
  ["math", 95],
  ["english", 88],
  ["science", 92]
];

let grades = new Map<string, number>(pairs);

// 从其他 Map 复制
let copy = new Map(grades);

6. Map vs 普通对象({})对比

特性MapObject ({})
键的类型任意类型(对象、函数、Symbol 等)只能是 string / symbol
键的顺序插入顺序保证ES2015+ 部分保证,但不完全可靠
大小获取map.sizeObject.keys(obj).length
遍历便利性原生支持 for…of、keys()、values()需要 Object.keys/entries
性能(频繁增删)更好一般
JSON 序列化不直接支持直接 JSON.stringify
推荐场景需要非字符串键、频繁增删、需顺序简单配置、需序列化

7. 最佳实践建议

  1. 优先使用 Map 当:
  • 键不是字符串(如对象、函数)。
  • 需要频繁添加/删除键值对。
  • 需要准确的插入顺序。
  • 需要 size 属性。
  1. 使用普通对象 当:
  • 键是字符串或 symbol。
  • 需要与 JSON 直接互操作。
  • 数据结构简单。
  1. 结合 interface 定义值类型
interface Product {
  name: string;
  price: number;
}

let inventory = new Map<string, Product>();

inventory.set("laptop", { name: "MacBook", price: 9999 });

小结:Map 类型速查

操作代码示例
创建new Map<string, number>()
添加map.set(key, value)
获取map.get(key)
检查存在map.has(key)
删除map.delete(key)
遍历键值for (const [k, v] of map)
大小map.size

如果您想深入了解 WeakMap(弱引用 Map,常用于缓存)、Map 与 Set 的结合使用、或 实际项目中的 Map 应用场景(如 Redux 状态管理、DOM 节点绑定数据),请告诉我!

文章已创建 3383

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部