为什么在JavaScript中你应该更偏向于使用Map而不是对象
JavaScript 开发者经常使用简单的对象作为键值存储,但 Map
数据结构有几个很有说服力的优点。让我们看看为什么在下一个项目中你可能会选择 Map
而不是普通的对象。
Map
的一个最重要的优点是它能够将任何值作为键,而不仅仅是字符串和符号。
// 对象的键总是会被转换为字符串形式
const obj = {};
obj[true] = "value1";
obj[1] = "value2";
obj[{ key: 1 }] = "value3";
console.log(Object.keys(obj));
// 打印结果: ["true", "1", "[object Object]"]
// 在Map中,键会保持它们原始的类型
const map = new Map();
map.set(true, "value1");
map.set(1, "value2");
map.set({ key: 1 }, "value3");
console.log([...map.keys()]);
// 打印结果: [true, 1, { key: 1 }]
你可以通过点击来进入全屏模式,然后在需要的时候退出全屏模式。
大小管理地图自带大小属性,而对象的大小则需要手动计算。
// 对象
const obj = { a: 1, b: 2, c: 3 };
const size = Object.keys(obj).length; // 需要转换为数组:
console.log(size); // 3
// Map
const map = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
console.log(map.size); // 3, 直接获取:
全屏 退出全屏
3. 更好的迭代优化地图旨在频繁添加和删除键值对,并且在迭代时性能更佳。
// 性能测试
const 迭代数 = 1000000;
// 对象
const obj = {};
console.time('对象');
for (let i = 0; i < 迭代数; i++) {
obj[`key${i}`] = i;
}
for (const key in obj) {
const value = obj[key];
}
console.timeEnd('对象');
const map = new Map(); // Map 对象
console.time('Map');
for (let i = 0; i < 迭代数; i++) {
map.set(`key${i}`, i);
}
for (const [key, value] of map) {
// 直接访问键值
}
console.timeEnd('Map');
进入全屏,退出全屏
4. 常见操作的简单明了的方法Map 提供了清晰且专为常见操作设计的函数。
// Map 操作
const map = new Map();
// 添加条目
map.set('key1', 'value1');
map.set('key2', 'value2');
// 检查是否存在
console.log(map.has('key1')); // true
// 获取值
console.log(map.get('key1')); // 'value1'
// 删除条目
map.delete('key1');
// 清空所有条目
map.clear();
// 与对象进行比较
const obj = {};
// 添加条目
obj.key1 = 'value1';
obj['key2'] = 'value2';
// 检查是否存在
console.log('key1' in obj); // true
// 或
console.log(obj.hasOwnProperty('key1')); // true
// 获取值
console.log(obj.key1); // 'value1'
// 删除条目
delete obj.key1;
// 清空所有条目
for (const key in obj) {
delete obj[key];
}
切换到全屏模式 切换回正常模式
5. 没有遇到原型链问题地图不会像对象那样遇到继承问题。
定义一个空对象
const obj = {};
console.log(obj.toString); // [Function: toString]
这表示对象有一个名为toString的函数
console.log(obj.hasOwnProperty('toString')); // false
这表示对象没有直接拥有toString属性
定义一个空的Map
const map = new Map();
console.log(map.get('toString')); // undefined
这表示Map中没有键名为toString的项
console.log(map.has('toString')); // false
这表示Map中不存在键名为toString的项
全屏模式,关闭
6. 使用多种方式轻松进行迭代过程地图内置了各种循环方法。
const map = new Map([
['name', 'John'],
['age', 30],
['city', '纽约市']
]);
// 遍历条目
for (const [key, value] of map) {
console.log(`${key}: ${value}`);
}
// 遍历键
for (const key of map.keys()) {
console.log(key);
}
// 遍历值
for (const value of map.values()) {
console.log(value);
}
// 使用 forEach
map.forEach((value, key) => {
console.log(`${key}: ${value}`);
});
点击进入全屏模式 点击退出全屏模式
何时仍然需要使用对象虽然地图很强大,但在某些情况下,还是用对象更好。
- 当你需要 JSON 序列化(Map 对象不能自动序列化)
- 当你需要访问简单的属性时
- 当你需要使用对象展开操作符
- 当你需要与 JSON API 交互时
// JSON 序列化
const obj = { name: 'John', age: 30 };
const jsonStr = JSON.stringify(obj); // 这会正常工作
const map = new Map([['name', 'John'], ['age', 30]]); // 定义一个 Map 对象
const jsonStr2 = JSON.stringify(map); // 结果会是空的 JSON 对象
// 不过,你可以将 Map 转换为 Object 来实现序列化
const mapAsObj = Object.fromEntries(map);
const jsonStr3 = JSON.stringify(mapAsObj); // 这也会正常工作
点击进入全屏模式 点击退出全屏模式
结尾当你需要以下情况时,地图是更好的选择:
- 查找路线和地点位置
- 规划旅行
- 确认方位
-
搜索附近的设施和便利服务
- 非字符串键值对
- 频繁的添加和移除
- 易于监控大小
- 更好的迭代性能表现
- 常见操作的清晰和一致的方法实现
- 不受原型链问题的困扰
仔细考虑清楚您的用例,但当这些好处符合您的需求时,不要害怕用Map
函数。
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦