乐闻世界logo
搜索文章和话题

ES6 中的 Map 和原生的对象有什么区别?

浏览23
6月24日 16:43

在 ES6 中,Map 是一种新的数据结构,它提供了一些原生对象(如普通的 JavaScript 对象)所不具备的特性。以下是 Map 和原生对象之间一些主要的区别:

  1. 键的类型

    • Map:可以使用任何类型的值(包括对象或原始值)作为键。
    • 对象:通常只能使用字符串或者 Symbol 作为键。虽然现代JavaScript引擎会自动将非字符串的键转换为字符串,但这可能导致键的冲突和预期之外的行为。
  2. 键的顺序

    • Map:键值对是有序的,Map 对象遍历时会根据元素的插入顺序进行。
    • 对象:在 ES2015 之前,对象的属性没有特定的顺序;但从 ES2015 开始,对象的属性遍历顺序是根据属性被添加到对象的顺序(对于字符串键)和整数键的大小来确定的,非整数键则按照创建顺序排列。
  3. 大小可获取

    • Map:可以直接获取到 Map 的大小,使用 map.size 属性。
    • 对象:通常需要手动计算属性的数量,例如通过 Object.keys(obj).length
  4. 性能

    • Map:在频繁添加和删除键值对的场景下,Map 通常提供更优的性能。特别是当涉及到大量键值对时,Map 的性能通常更稳定。
    • 对象:当作为少量属性的集合时,原生对象也可能表现出良好的性能。
  5. 默认键

    • Map:不包含默认键,只包含显式插入的键。
    • 对象:原型链上的属性和方法可以被继承,对象默认会含有诸如 toStringhasOwnProperty 这样的方法,这可能会在某些使用场景中造成问题。
  6. 迭代

    • MapMap 对象可以直接被迭代,提供了几个迭代方法,包括 map.keys()map.values()map.entries(),以及 map.forEach() 方法。
    • 对象:对象的属性需要使用 for...in 循环或 Object.keys()Object.values()Object.entries() 加上 forEach 方法等进行迭代。
  7. 序列化

    • MapMap 对象不能直接使用 JSON.stringify 进行序列化。
    • 对象:对象可以直接被序列化为 JSON 字符串。

例如,如果我们需要一个键值对集合来记录用户的唯一标识符(这些标识符可能是数字、字符串、甚至是对象),并且希望保持插入顺序,那么 Map 就特别适合这种用例。使用 Map 我们可以这样实现:

javascript
let userRoles = new Map(); let user1 = { name: "Alice" }; let user2 = { name: "Bob" }; // 添加用户角色 userRoles.set(user1, 'admin'); userRoles.set(user2, 'editor'); // 获取Map的大小 console.log(userRoles.size); // 2 // 按插入顺序遍历用户角色 for (let [user, role] of userRoles.entries()) { console.log(`${user.name}: ${role}`); }

在这个例子中,我们使用对象 user1user2 作为键,这在普通的对象中是无法做到的,因为对象的键会被转换为字符串。

标签:前端ES6