JS — ES6 知识点笔记: Map

含义、基本用法

Map 是 ES6 引入的一种新的数据结构,用于存储键值对。与普通对象不同,Map 的键可以是任何数据类型,包括对象、函数等

JS
// 创建 Map
const myMap = new Map();

// 基本操作
myMap.set('name', 'Alice');
myMap.set(1, 'number one');
myMap.set({}, 'object key');

console.log(myMap.get('name')); // 'Alice'
console.log(myMap.size); // 3
点击展开查看更多

了解为什么在 ES6 引入 Map

JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。

请看看下面代码:

JS
const data = {};
const element = document.getElementById('myDiv');

data[element] = 'metadata';
data['[object HTMLDivElement]'] // "metadata"
点击展开查看更多

上面代码原意是将一个 DOM 节点作为对象data的键,但是由于对象只接受字符串作为键名,所以element被自动转为字符串[object HTMLDivElement],为了解决这个问题,ES6 提供了 Map 数据结构。

它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说:

如果你需要“键值对”的数据结构,Map 比 Object 更合适。

Map 和 Obj 的区别

特性 Map Object
键的类型 任意类型 字符串或 Symbol
顺序 插入顺序 不保证顺序(ES6后有一定顺序)
大小 size 属性 需要手动计算
性能 频繁增删时更优 静态数据时更优
默认键 有原型链上的键

Map 的常用方法

1. 基本操作

JS
const map = new Map();

// 添加元素
map.set('name', 'John');
map.set('age', 30);
map.set('isStudent', false);

// 获取元素
console.log(map.get('name')); // 'John'

// 检查是否存在
console.log(map.has('age')); // true

// 删除元素
map.delete('isStudent');

// 清空 Map
// map.clear();

// 获取大小
console.log(map.size); // 2
点击展开查看更多

2. 遍历 Map

Map 结构原生提供三个遍历器生成函数和一个遍历方法

  1. Map.prototype.keys():返回键名的遍历器。
  2. Map.prototype.values():返回键值的遍历器。
  3. Map.prototype.entries():返回所有成员的遍历器。
  4. Map.prototype.forEach():遍历 Map 的所有成员
JS
const userMap = new Map([
  ['name', 'Alice'],
  ['age', 25],
  ['city', 'New York']
]);

// 遍历键
for (let key of userMap.keys()) {
  console.log(key); // 'name', 'age', 'city'
}

// 遍历值
for (let value of userMap.values()) {
  console.log(value); // 'Alice', 25, 'New York'
}

// 遍历键值对
for (let [key, value] of userMap.entries()) {
  console.log(`${key}: ${value}`);
}

// 使用 forEach
userMap.forEach((value, key) => {
  console.log(`${key} = ${value}`);
});

/*
console.log():
    name = Alice
    age = 25
    city = New York
*/
点击展开查看更多

3.初始化 Map

JS
// 从数组初始化
const map1 = new Map([
  ['key1', 'value1'],
  ['key2', 'value2'],
  ['key3', 'value3']
]);

// 从对象转换
const obj = { a: 1, b: 2, c: 3 };
const map2 = new Map(Object.entries(obj));

// Map 转回对象
const newObj = Object.fromEntries(map2);
点击展开查看更多

4. Map 的合并

JS
function mergeMaps(...maps) {
  const merged = new Map();
  maps.forEach(map => {
    map.forEach((value, key) => {
      merged.set(key, value);
    });
  });
  return merged;
}

const map1 = new Map([['a', 1], ['b', 2]]);
const map2 = new Map([['b', 3], ['c', 4]]);
const merged = mergeMaps(map1, map2);
// Map(3) {'a' => 1, 'b' => 3, 'c' => 4}
点击展开查看更多

5. Map 的序列化

JS
// Map 转 JSON
function mapToJson(map) {
  return JSON.stringify(Array.from(map.entries()));
}

// JSON 转 Map
function jsonToMap(jsonStr) {
  return new Map(JSON.parse(jsonStr));
}

const myMap = new Map([['a', 1], ['b', 2]]);
const json = mapToJson(myMap); // '[["a",1],["b",2]]'
const newMap = jsonToMap(json);
点击展开查看更多

实际应用

1. 对象关联

JS
// 使用对象作为键
const userPreferences = new Map();
const user1 = { id: 1, name: 'Alice' };
const user2 = { id: 2, name: 'Bob' };

userPreferences.set(user1, { theme: 'dark', language: 'en' });
userPreferences.set(user2, { theme: 'light', language: 'fr' });

console.log(userPreferences.get(user1)); // {theme: 'dark', language: 'en'}
点击展开查看更多

2. 计算出现次数/频率

JS
function countFrequency(arr) {
  const frequencyMap = new Map();
  
  arr.forEach(item => {
    frequencyMap.set(item, (frequencyMap.get(item) || 0) + 1);
  });
  
  return frequencyMap;
}

const numbers = [1, 2, 3, 2, 1, 3, 3, 4, 1];
console.log(countFrequency(numbers));
// Map(4) {1 => 3, 2 => 2, 3 => 3, 4 => 1}
点击展开查看更多

总结

版权声明

作者: Donghai

链接: https://mgrowup.com/posts/js/es6-map/

许可证: CC BY-NC-SA 4.0

文章已根据知识共享署名-非商业性使用-相同方式共享4.0国际许可协议授权。请注明来源,仅非商业使用,并保持相同的许可协议。

评论

开始搜索

输入关键词搜索文章内容

↑↓
ESC
⌘K 快捷键