Map和Set是解决对象局限的专用工具:Map支持任意类型键、保持插入顺序、无原型污染、原生size属性;Set自动去重、O(1)查询、正确处理NaN、强调存在性而非索引。
Map 和 Set 不是对象的替代品,而是解决对象固有局限的专用工具。它们和普通对象在设计目标、行为规则和性能表现上存在本质差异。
普通对象({})本质上是字符串键的映射,而 Map 是真正支持任意类型键的键值对集合:
{[1]: 'a'} 实际等价于 {'1': 'a'})Object.prototype,不会因 map.has('toString') 这类操作误判;对象若未用 Object.create(null) 创建,就可能被原型链上的同名属性干扰size 属性;对象需靠 Object.keys(obj).length,且无法准确统计不可枚举或 Symbol 键Set
是专为“唯一值集合”设计的数据结构,不是数组的简化版:
NaN === NaN 为 false,但 Set 中仍视为相同)会被静默忽略;数组去重需手动过滤,时间复杂度 O(n²)set.has(value) 平均时间复杂度为常数级;数组用 includes() 或 indexOf() 是 O(n)NaN 重复;而对象键无法存两个 NaN(都会变成字符串 'NaN'),数组也无法直接判断 NaN 是否已存在set[0] 无效),强调“存在性”而非“位置”,避免误用当你需要以非字符串值为标识、或对键值对操作有明确顺序和性能要求时:
map.keys().next().value 可快速获取最早插入项当你关注“某值是否存在”或“确保不重复”时,Set 比数组或对象更自然、更高效:
[...new Set(arr)] 是最简洁可靠的写法,兼容所有类型(含对象引用)['read', 'edit', 'delete']),用 set.has('edit') 判断权限,比数组 includes 快得多new Set([...a].filter(x => b.has(x)))))