Javascript ES6 中的地图与对象,何时使用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32600157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Maps vs Objects in ES6, When to use?
提问by Matthew Harwood
Use maps over objects when keys are unknown until run time, and when all keys are the same type and all values are the same type.
Use objects when there is logic that operates on individual elements.
当键在运行时之前未知,并且所有键的类型和所有值的类型都相同时,请使用对象映射。
当存在对单个元素进行操作的逻辑时使用对象。
Question:
题:
What is an applicable example of using Maps over objects? in particular, "when would keys be unknown until runtime?"
在对象上使用地图的适用示例是什么?特别是,“在运行之前什么时候密钥是未知的?”
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));
采纳答案by Bergi
What is an applicable example of using Maps over objects?
在对象上使用地图的适用示例是什么?
I think you've given one good example already: You at least need to use Map
s when you are using objects (including Function objects) as keys.
我想你已经给出了一个很好的例子:Map
当你使用对象(包括函数对象)作为键时,你至少需要使用s 。
in particular, "when would keys be unknown until runtime?"
特别是,“在运行之前什么时候密钥是未知的?”
Whenever they are not known at compile time. In short, you should always use a Map
when you need a key-value collection. A good indicator that you need a collection is when you add and remove values dynamically from the collection, and especially when you don't know those values beforehand (e.g. they're read from a database, input by the user, etc).
每当它们在编译时未知时。简而言之,Map
当您需要键值集合时,您应该始终使用 a 。您需要集合的一个很好的指标是当您从集合中动态添加和删除值时,尤其是当您事先不知道这些值时(例如,它们是从数据库中读取的,由用户输入等)。
In contrast, you should be using objects when you know which and how many properties the object has while writing the code - when their shape is static. As @Felix has put it: when you need a record. A good indicator for needing that is when the fields have different types, and when you never need to use bracket notation (or expect a limited set of property names in it).
相反,当您在编写代码时知道对象具有哪些属性和多少属性时,您应该使用对象 - 当它们的形状是静态的。正如@Felix 所说:当您需要记录时。需要的一个很好的指标是当字段具有不同的类型时,以及当您永远不需要使用括号表示法(或期望其中包含一组有限的属性名称)时。
回答by Bergi
I think that with ES2015's Map
only two reasons are left to use plain objects:
我认为 ES2015Map
只剩下两个使用普通对象的原因:
- You don't want to iterate over the properties of an object type at all
- or you do but the property order doesn't matter and you can distinguish the program from the data levelwhen iterating
- 您根本不想迭代对象类型的属性
- 或者你这样做,但属性顺序无关紧要,你可以在迭代时将程序与数据级别区分开来
When is the property order unimportant?
什么时候财产顺序不重要?
- if you have only a single value and some functions that should be associated explicitly with it (like
Promise
- which is a proxy for a future value - andthen
/catch
) - if you have a struct/record-like data structure with a static set of properties known at "compile time" (usually structs/records aren't iterable)
- 如果您只有一个值和一些应该与其显式关联的函数(例如
Promise
- 这是未来值的代理 - 和then
/catch
) - 如果您有一个类似结构/记录的数据结构,其中包含一组在“编译时”已知的静态属性(通常结构/记录不可迭代)
In all other cases you might consider using Map
, because it preserves property order and separates the program (all properties assigned to the Map
object) from the data level (all entries in the Map
itself).
在所有其他情况下,您可能会考虑使用Map
,因为它保留了属性顺序并将程序(分配给Map
对象的所有属性)与数据级别(Map
自身中的所有条目)分开。
What are the drawbacks of Map
?
有什么缺点Map
?
- you lose the concise object literal syntax
- you need custom replacers for JSON.stringyfy
- you lose destructuring, which is more useful with static data structures anyway
- 你失去了简洁的对象文字语法
- 您需要 JSON.stringyfy 的自定义替换器
- 你失去了解构,无论如何这对静态数据结构更有用
回答by Bergi
Use maps over objects when keys are unknown until run time, and when all keys are the same type and all values are the same type.
当键在运行时之前未知,并且所有键的类型和所有值的类型都相同时,请使用对象映射。
I have no idea why someone would write something so obviously wrong. I have to say, people are finding more and more wrong and/or questionable content on MDN these days.
我不知道为什么有人会写出如此明显错误的东西。我不得不说,如今人们在 MDN 上发现越来越多的错误和/或有问题的内容。
Nothing in that sentence is correct. The main reason to use maps is when you want object-valued keys. The idea that the values should be the same type is absurd--although they might be, of course. The idea that one shouldn't use objects when keys are unknown until run time is equally absurd.
这句话中没有什么是正确的。使用映射的主要原因是当您需要对象值键时。值应该是相同类型的想法是荒谬的——尽管它们当然可能是。当键在运行时之前未知时不应该使用对象的想法同样荒谬。
回答by slideshowp2
One of the difference between Map
and Object
is:
Map
和之间的区别之一Object
是:
Map
can use complex data type as its key. like this:
Map
可以使用复杂数据类型作为其键。像这样:
const fn = function() {}
const m = new Map([[document.body, 'stackoverflow'], [fn, 'redis']]);
m.get(document.body) // 'stackoverflow'
m.get(fn) //'redis'
watch out:For complex data type, If you want to get the value, you must pass the same reference as the key.
注意:对于复杂数据类型,如果要获取值,必须传递与键相同的引用。
Object
, it only accept simple data type(number
, string
) as its key.
Object
,它只接受简单的数据类型( number
, string
) 作为它的键。
const a = {};
a[document.body] = 'stackoverflow';
console.log(a) //{[object HTMLBodyElement]: "stackoverflow"}
回答by codejockie
Object
s are similar to Map
s in that both let you set keys to values, retrieve those values, delete keys, and detect whether something is stored at a key. Because of this (and because there were no built-in alternatives), Object
s have been used as Map
s historically; however, there are important differences that make using a Map
preferable in certain cases:
Object
s 与 s 的相似之处Map
在于,两者都可以让您将键设置为值、检索这些值、删除键以及检测某个键是否存储了某些内容。正因为如此(并且因为没有内置的替代品),Object
s 在Map
历史上被用作s;但是,Map
在某些情况下,使用 a更可取的重要区别是:
- The keys of an
Object
areString
s andSymbol
s, whereas they can be any value for aMap
, including functions, objects, and any primitive. - The keys in
Map
are ordered while keys added to object are not. Thus, when iterating over it, aMap
object returns keys in order of insertion. - You can get the size of a
Map
easily with thesize
property, while the number of properties in anObject
must be determined manually. - A
Map
is an iterable and can thus be directly iterated, whereas iterating over anObject
requires obtaining its keys in some fashion and iterating over them. - An
Object
has a prototype, so there are default keys in the map that could collide with your keys if you're not careful. As of ES5 this can be bypassed by usingmap = Object.create(null)
, but this is seldom done. - A
Map
may perform better in scenarios involving frequent addition and removal of key pairs.
- an 的键
Object
是String
s 和Symbol
s,而它们可以是 a 的任何值Map
,包括函数、对象和任何原语。 - 键
Map
是有序的,而添加到对象的键不是。因此,当对其进行迭代时,Map
对象会按插入顺序返回键。 - 您可以
Map
使用size
属性轻松获取 a 的大小,而Object
必须手动确定a 中的属性数量。 - A
Map
是可迭代的,因此可以直接迭代,而迭代 anObject
需要以某种方式获取其键并对其进行迭代。 - An
Object
有一个原型,所以如果你不小心,地图中有默认的键可能会与你的键发生冲突。从 ES5 开始,这可以通过使用 绕过map = Object.create(null)
,但很少这样做。 - A
Map
在涉及频繁添加和删除密钥对的场景中可能表现更好。
回答by Dan Dascalescu
This question is a duplicate of but until it's closed, here's my answer from over there:
In addition to the other answers, I've found that Maps are more unwieldy and verbose to operate with than objects.
除了其他答案之外,我发现 Maps 比对象更笨拙和冗长。
obj[key] += x
// vs.
map.set(map.get(key) + x)
This is important, because shorter code is faster to read, more directly expressive, and better kept in the programmer's head.
这很重要,因为更短的代码读起来更快,表达更直接,并且更好地保留在程序员的脑海中。
Another aspect: because set() returns the map, not the value, it's impossible to chain assignments.
另一个方面:因为 set() 返回的是映射,而不是值,所以不可能链式赋值。
foo = obj[key] = x; // Does what you expect
foo = map.set(key, x) // foo !== x; foo === map
Debugging maps is also more painful. Below, you can't actually see what keys are in the map. You'd have to write code to do that.
调试地图也比较痛苦。在下面,您实际上无法看到地图中的键。您必须编写代码才能做到这一点。
Objects can be evaluated by any IDE:
任何 IDE 都可以评估对象: