Skip to content

JavaScript中Maps和对象的区别是什么?

大多数JavaScript开发人员都熟悉对象,并且可能每天都在使用它们。另一方面,Maps并不常见,但仍然非常有用。虽然在表面上与对象非常相似,但它们有一些非常重要的区别。让我们来看看它们。

键类型

对象键仅限于使用字符串和符号。另一方面,Maps可以使用任何类型的值作为它们的键,包括函数和对象。这在许多不同的场景中都很有用,例如记忆化和数据关联。

const people = [
  { id: 1, name: 'John', surname: 'Doe', age: 30 },
  { id: 2, name: 'Jane', surname: 'Doe', age: 28 },
];

const peopleIndex = people.reduce((index, person) => {
  index[person.id] = `${person.name} ${person.surname}`;
  return index;
}, {});
// peopleIndex = {
//   '1': 'John Doe',
//   '2': 'Jane Doe',
// }

const peopleIndexMap = new Map(
  people.map(person => [person, `${person.name} ${person.surname}`])
);

// peopleIndexMap = Map {
//   { id: 1, name: 'John', surname: 'Doe', age: 30 } => 'John Doe',
//   { id: 2, name: 'Jane', surname: 'Doe', age: 28 } => 'Jane Doe',
// }

迭代

通常使用Object.keys()Object.values()Object.entries()来进行对象迭代。所有这些方法都作为Maps的原型的一部分可用,但它们的效率要高得多。原因是这些Map方法返回迭代器,它们是惰性的,只有在需要时才迭代键或值。此外,Maps公开了一个迭代器,可以与for...of循环一起使用。

const obj = { a: 1, b: 2, c: 3 };
const objEntries = Object.entries(obj);
// ['a', 1], ['b', 2], ['c', 3]
for (const [key, value] of objEntries)
  console.log(`${key}: ${value}`);

const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
const mapEntries = [...map.entries()]; // 与[...map]相同
// [['a', 1], ['b', 2], ['c', 3]]
for (const [key, value] of map)
  console.log(`${key} => ${value}`);

其他区别

除了已经提到的两个主要区别之外,还有一些其他不太明显的区别。这些包括以下内容:

  • 对象的大小需要手动计算。而Map有一个内置的size属性,可以用来跟踪键值对的数量。
  • 您可以使用in运算符或Object.prototype.hasOwnProperty()来检查对象中是否存在给定的键。Map.prototype.has()可以实现相同的功能。
  • 清除对象需要手动操作,在某些情况下可能不容易。Map通过使用Map.prototype.clear()来解决这个问题。
  • 对象从原型继承一些键,而Map则不会。