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

Mat*_*ood 80 javascript javascript-objects ecmascript-6

参考:MDN地图

当密钥未知时直到运行时,并且当所有键都是相同类型且所有值都是相同类型时,请使用对象上的映射.

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

题:

在对象上使用地图的适用示例是什么?特别是"什么时候直到运行时才能知道密钥?"

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));
Run Code Online (Sandbox Code Playgroud)

Ber*_*rgi 48

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

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

特别是"什么时候直到运行时才能知道密钥?"

每当他们在编译时都不知道.简而言之,您应该Map在需要键值集合时始终使用.您需要集合的一个好指标是当您从集合中动态添加和删除值时,尤其是当您事先不知道这些值时(例如,它们是从数据库中读取,由用户输入等).

相反,当您知道对象在编写代码时具有哪些属性和多少属性时,您应该使用对象 - 当它们的形状是静态的时.正如@Felix所说:当你需要一个记录时.需要的一个很好的指标是当字段具有不同的类型,并且您永远不需要使用括号表示法(或期望其中有一组有限的属性名称)时.

  • 或者从另一个角度来看:每当您需要在数据级别(例如“for..of”)而不是程序级别(例如“for..in”)迭代对象的属性时,请使用“Map”。有关此条款的更多信息[在此回复中](http://stackoverflow.com/a/38777177/6445533)。 (2认同)

小智 25

我认为使用ES2015 Map只剩下两个原因:使用普通对象:

房产订单何时不重要?

  • 如果你只有一个值和一些应该与它明确关联的函数(比如Promise- 这是未来值的代理 - 和then/ catch)
  • 如果你有一个类似结构/记录的数据结构,其中一组静态属性在"编译时"已知(通常结构/记录不可迭代)

在所有其他情况下,您可以考虑使用Map,因为它保留了属性顺序并将程序(分配给Map对象的所有属性)与数据级别(Map自身中的所有条目)分开.

有什么缺点Map

  • 你失去了简洁的对象文字语法
  • 你需要JSON.stringyfy的自定义替换器
  • 你失去了解构,这对静态数据结构更有用

  • 你说得对。“Map”可能更快,因为它纯粹基于哈希,而“Object”则稍微复杂一些。谢谢! (2认同)

小智 9

当密钥未知时直到运行时,并且当所有键都是相同类型且所有值都是相同类型时,请使用对象上的映射.

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

那句话中没有任何内容是正确的.使用地图的主要原因是您需要对象值键.价值观应该是同一类型的想法是荒谬的 - 当然,尽管它们可能是荒谬的.在运行时直到键时不应该使用对象的想法同样荒谬.

  • 我不明白这个想法有什么可笑的?当您需要集合时,它们通常是严格类型化的(当然可能有例外)。另外,我认为不再使用集合对象(当“Map”可用时)是个好建议。 (2认同)
  • 是的,我觉得这有点奇怪,但这个想法很好。我猜他们认为“在运行时之前密钥是未知的”已经创建了一个集合。有更好的措辞的想法吗? (2认同)

Joh*_*edy 6

Objects 与 s 类似Map,两者都允许您将键设置为值、检索这些值、删除键以及检测键中是否存储了某些内容。正因为如此(并且因为没有内置的替代方案),Objects 历史上一直被用作Maps ;Map然而,在某些情况下,存在一些重要的差异,使得使用更可取:

  • an 的键ObjectStrings 和Symbols,而它们可以是 a 的任何值Map,包括函数、对象和任何基元。
  • 中的键Map是有序的,而添加到对象中的键则不是。因此,当对其进行迭代时,Map对象会按插入顺序返回键。
  • Map您可以通过属性轻松获取 a 的大小size,而 an 中属性的数量Object必须手动确定。
  • AMap是可迭代的,因此可以直接迭代,而迭代 anObject需要以某种方式获取其键并迭代它们。
  • AnObject有一个原型,因此如果您不小心,地图中的默认键可能会与您的键发生冲突。从 ES5 开始,这可以通过使用 来绕过map = Object.create(null),但很少这样做。
  • Map在频繁添加和删除密钥对的场景中,A可能会表现得更好。

MDN


sli*_*wp2 5

Map和之间的区别之一Object是:

Map可以使用复杂数据类型作为其键。像这样:

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

m.get(document.body) // 'stackoverflow'
m.get(fn) //'redis'
Run Code Online (Sandbox Code Playgroud)

注意:对于复杂数据类型,如果要获取值,必须传递与键相同的引用。

Object,它只接受简单的数据类型( number, string) 作为它的键。

const a = {};
a[document.body] = 'stackoverflow';

console.log(a) //{[object HTMLBodyElement]: "stackoverflow"}
Run Code Online (Sandbox Code Playgroud)