地图与对象在ES6,何时使用?

参考:MDN地图

当键未知时,使用映射到对象上,直到运行时,以及所有键都是相同types,并且所有值都是相同types。

当存在对单个元素进行操作的逻辑时使用对象。

题:

什么是在地图上使用对象的适用示例? 特别是“什么时候键直到运行时才知道?”

var myMap = new Map(); var keyObj = {}, keyFunc = function () { return 'hey'}, keyString = "a string"; // setting the values myMap.set(keyString, "value associated with 'a string'"); myMap.set(keyObj, "value associated with keyObj"); myMap.set(keyFunc, "value associated with keyFunc"); console.log(myMap.get(keyFunc)); 

什么是在地图上使用对象的适用示例?

我想你已经给出了一个很好的例子:当你使用对象(包括Function对象)作为关键字时,你至less需要使用Map

特别是“什么时候键直到运行时才知道?”

只要在编译时不知道它们。 总之,当你需要一个键值集合时,你应该总是使用一个Map 。 一个很好的指示,你需要一个集合是当你从集合中dynamic地添加和删除值,特别是当你事先不知道这些值(例如,他们从数据库读取,由用户input等)。

相反,当你知道对象在编写代码时有哪些属性和有多less属性时,你应该使用对象 – 当它们的形状是静态的。 正如@Felix所说的那样:当你需要一个logging时 。 需要的一个很好的指示是当字段具有不同的types时,以及不需要使用括号表示法(或期望在其中使用有限的一组属性名称)时。

我认为使用ES2015的Map只有两个原因是使用普通对象:

  • 你不想遍历一个对象types的属性
  • 或者你做的,但财产秩序无关紧要,你可以在迭代时区分程序和数据级别

物业订单何时不重要?

  • 如果你只有一个值和一些函数,应该明确地与它关联(如Promise – 这是一个未来价值的代理 – then / catch
  • 如果您在“编译时”已知具有一组静态属性的结构/类似于logging的数据结构(通常结构/logging不可迭代)

在所有其他情况下,您可能会考虑使用Map ,因为它保留了属性顺序,并从数据级别( Map本身中的所有条目)中分离出程序(分配给Map对象的所有属性)。

Map什么缺点?

  • 你失去了简洁的对象文字语法
  • 您需要为JSON.stringyfy定制replace器
  • 它可能比纯粹的类似hashmap的对象慢
  • 你会失去解构,无论如何,这对静态数据结构更有用

当键未知时,使用映射到对象上,直到运行时,以及所有键都是相同types,并且所有值都是相同types。

我不知道为什么有人会写这么明显错误的东西。 我不得不说,现在人们在MDN上发现越来越多的错误和/或可疑的内容。

这句话没有什么是正确的。 使用地图的主要原因是当你想要对象值的键。 价值观应该是同一types的想法是荒谬的 – 尽pipe它们可能是当然的。 当密钥未知时,不应该使用对象的想法,直到运行时间同样荒谬。

这个问题是重复的 但直到它closures,这是我在那里的答案 :

除了其他的答案,我发现地图比对象更难处理和冗长。

 obj[key] += x // vs. map.set(map.get(key) + x) 

这一点很重要,因为较短的代码更快速的阅读,更直接的expression,更好地保存在程序员的脑海中 。

另一方面:因为set()返回的是地图,而不是值,所以不可能链接任务。

 foo = obj[key] = x; // Does what you expect foo = map.set(key, x) // foo !== x; foo === map 

debugging地图也更加痛苦。 下面,你不能真正看到地图上的什么键。 你必须编写代码来做到这一点。

祝你好运评估一个Map Iterator

对象可以由任何IDE进行评估:

WebStorm评估一个对象

MapObject之间的区别之一是:

Map可以使用复杂的数据types作为其关键。 喜欢这个:

 const fn = function() {} const m = new Map([[document.body, 'stackoverflow'], [fn, 'redis']]); m.get(document.body) // 'stackoverflow' m.get(fn) //'redis' 

注意:对于复杂的数据types,如果你想得到这个值,你必须传递和键一样的参考。

Object ,它只接受简单的数据types( numberstring )作为其键。

 const a = {}; a[document.body] = 'stackoverflow'; console.log(a) //{[object HTMLBodyElement]: "stackoverflow"}