怎样使用javascriptMap与Set_它们与对象有何不同?

Map和Set是ES6引入的专用集合类型:Map支持任意类型键值对且有序,Set专注自动去重存储唯一值;二者均比Object更可靠,适用于动态键、非字符串键、顺序遍历及纯净数据场景。

JavaScript 中的 MapSet 是 ES6 引入的两种新集合类型,它们比普通对象(Object)更专一、更可靠,尤其适合处理键值对和唯一值场景。核心区别在于:对象的键只能是字符串或 Symbol,而 Map 的键可以是任意类型;Set 则专注“去重存储”,不涉及键值映射。

Map:真正灵活的键值容器

Map 是一个有序的键值对集合,键可以是函数、对象、数字、布尔值甚至 null,不会被强制转为字符串 —— 这是它和普通对象最本质的区别。

  • 创建用 new Map(),不能像对象那样字面量直接写({} 不是 Map
  • 增删查用方法:set(key, value)get(key)has(key)delete(key)size 属性
  • 遍历更自然:map.keys()map.values()map.entries() 都返回迭代器,可直接用于 for...of
  • 示例:
    const m = new Map();
    m.set({}, 'objKey');
    m.set(true, 'boolKey');
    m.get({}) // undefined(因为对象引用不同)
    m.get(true) // 'boolKey'

Set:只存唯一值,自动去重

Set 是一个值的集合,内部自动确保所有值唯一(基于 SameValueZero 比较,即 0 === -0NaN 等于自身),不关心“键”,也不提供索引访问。

  • 创建:new Set([1, 2, 2, 3]) → 自动变成 {1, 2, 3}
  • 常用方法:add(value)has(value)delete(value)sizeclear()
  • 去重实用技巧:
    [...new Set([1, 2, 2, 3])] // [1, 2, 3]
    Array.from(new Set(str.split(''))).join('') // 字符串去重
  • 注意:Set 存对象时按引用判断,两个内容相同但不同的对象仍被视为不同元素

与普通对象(Object)的关键差异

对象不是为通用数据结构设计的,它本质是属性容器,带原型链和默认方法,容易误用。

  • 键类型限制:对象键会被转成字符串({true: 1} 实际是 {'true': 1}),Map 没这问题
  • 顺序保障:对象属性遍历顺序在 ES2015 后虽有规范,但仍受数字键影响(如 obj[100] 可能排前面);Map 始终按插入顺序
  • 大小获取:对象要手动 Object.keys(obj).lengthMapSet 直接有 .size
  • 原型污染风险:对象可能意外继承 toString 等属性;Map/Set 是纯净数据结构,无原型干扰

什么时候该用哪个?

不必强行替换所有对象,按需选择:

  • 需要键是对象/函数/非字符串值 → 用 Map
  • 只关心“有没有这个值”,且要自动去重 → 用 Set
  • 配置项、JSON 数据、带语义的属性名(如 user.name)→ 还是用对象
  • 频繁增删键值、关注插入顺序、动态键名 → Map 更合适

基本上就这些。Map 和 Set 不复杂,但容易忽略它们解决的老问题 —— 对象不是万能的数据容器。