地图与对象在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地图也更加痛苦。 下面,你不能真正看到地图上的什么键。 你必须编写代码来做到这一点。
对象可以由任何IDE进行评估:
Map
和Object
之间的区别之一是:
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( number
, string
)作为其键。
const a = {}; a[document.body] = 'stackoverflow'; console.log(a) //{[object HTMLBodyElement]: "stackoverflow"}