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

IT技术 javascript ecmascript-6 javascript-objects
2021-02-22 10:52:02

参考: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));
6个回答

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

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

特别是,“在运行之前什么时候密钥是未知的?”

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

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

或者从另一个角度来看:每当您需要在数据级别(例如for..of)而不是程序级别(例如for..in迭代对象的属性时,请使用Map. 在此回复中有关此条款的更多信息
2021-05-10 10:52:02
我还将添加一个事实作为评论,即任何时候您不知道您的密钥将是哪种类型并且您不希望字符串作为关键数据类型,然后使用 map stackoverflow.com/questions/32600157/...
2021-05-15 10:52:02

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

什么时候财产顺序不重要?

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

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

有什么缺点Map

  • 你失去了简洁的对象文字语法
  • 您需要 JSON.stringyfy 的自定义替换器
  • 你失去了解构,无论如何这对静态数据结构更有用
这条线让我非常担心:“它可能比​​纯的、类似哈希图的对象慢” 由于性能改进,我想用地图替换我的所有对象。但是你说它更慢......
2021-04-17 10:52:02
你说得对。Map可能更快,因为它纯粹基于散列,而Object有点复杂。谢谢!
2021-05-01 10:52:02

当键在运行时之前未知,并且所有键的类型和所有值的类型都相同时,请使用对象映射。

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

这句话中没有什么是正确的。使用映射的主要原因是当您需要对象值键时。值应该是相同类型的想法是荒谬的——尽管它们当然可能是。当键在运行时之前未知时不应使用对象的想法同样荒谬。

同意。MDN 有很好的文档,但他们应该坚持记录 API 文档,而不是试图给出编程建议。
2021-05-04 10:52:02
我不明白这个想法有什么荒谬之处?当您需要集合时,它们通常是严格类型的(当然可能有例外)。此外,我认为不再使用集合对象(当Map可用时)是一个很好的建议。
2021-05-10 10:52:02
对于通常严格类型化的集合而言,这与说严格类型化的东西应该是一个集合在逻辑上是不同的。
2021-05-10 10:52:02
是的,我认为这有点奇怪,但这个想法很好。我猜他们认为“键在运行时之前是未知的”已经做了一个集合。有更好的措辞的想法吗?
2021-05-16 10:52:02

Map之间的区别之一Object是:

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

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

m.get(document.body) // 'stackoverflow'
m.get(fn) //'redis'

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

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

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

console.log(a) //{[object HTMLBodyElement]: "stackoverflow"}

Objects 与 s 的相似之处Map在于,两者都可以让您将键设置为值、检索这些值、删除键以及检测某个键是否存储了某些内容。正因为如此(并且因为没有内置的替代品),Objects 在Map历史上被用作s;然而,Map在某些情况下使用 a 的重要区别是

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

MDN