4

MDN 文档Map说:

如果您仍然不确定使用哪一个 [object or map],请问自己以下问题:

  • 键在运行时通常是未知的,您是否需要动态查找它们?

  • [...]

这些都是你想要一个集合的地图的迹象。[...] https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map

但是我也可以用方括号动态地为对象设置键(即。myObject[dynamicKey])。

当我拥有动态键时,是否还有其他使用原因,maps而不仅仅是为了“符合地图目的”作为一个集合?

4

4 回答 4

2

使用任意键的原因Map是避免名称冲突。例如对于普通对象:

let a = {};

function foo(key) {
  console.log(a[key] === undefined ? "Unset" : "Set");
  a[key] = "Hi";
  console.log(a[key]);
  console.log("" + a);
}

foo("goodKey");  // Unset, Hi, [object Object]
foo("toString"); // Set, Hi, TypeError: can't convert a to primitive type

上面我们与Object.prototype.toString.

我们Map很好:

let a = new Map();

function foo(key) {
  console.log(a.get(key) === undefined ? "Unset" : "Set");
  a.set(key, "Hi");
  console.log(a.get(key));
  console.log("" + a);
}

foo("goodKey");  // Unset, Hi, [object Map]
foo("toString"); // Unset, Hi, [object Map]

于 2016-12-12T03:39:43.567 回答
1

它与同一文档中的前一点有关:

一个对象有一个原型,所以地图中有默认键。

传统上,当您遍历一个对象时(这就是“动态查找 [keys]”的意思),您需要过滤掉原型属性:

for( var key in obj ) {
    if( obj.hasOwnProperty(key) ) {
        // do something
    }
}

当您遍历 Map 时,您可以跳过额外的检查,因为它没有自己的属性与原型属性混合在一起。

于 2016-12-09T20:03:21.357 回答
1

对象仅支持数字和字符串作为键。地图还支持对象作为键。如果您的密钥在运行时之前是未知的,您可能无法确定密钥的类型。所以地图更安全。

我认为在将 ECMAScript 6 代码转换为 ECMAScript 5 时不应该使用 Map。使用 Map 所需的 polyfill 对性能不利。

于 2016-12-09T20:44:43.040 回答
0

但是为对象赋值仍然存在问题。原因是键总是被转换为对象中的字符串。

例如:

let author1 = { name: "Name1" };
let author2 = { name: "Name2" };

let mostRecentReply = {};

mostRecentReply[author1] = "Test1";
mostRecentReply[author2] = "Test2";

console.log( mostRecentReply[author1] );
console.log( mostRecentReply[author2] );

将输出以下内容:

Test2
Test2

使用地图解决了这个问题:

let mostRecentReply = new Map();
mostRecentReply.set(author1, "Test1");
mostRecentReply.set(author2, "Test2");

console.log( mostRecentReply.get(author1) );
console.log( mostRecentReply.get(author2) );

将输出:

Test1
Test2
于 2016-12-10T12:51:22.617 回答