在JavaScript中使用对象作为属性键

7
这段代码在做什么?
var a = {a:1};
var b = {b:2};
var c = {};

c[a] = 1;
c[b] === 1 // true!

c[b] = 2;
c[a] === 2 // true!

具体来说,为什么在c中查找b会返回存储在a属性中的值?

在JavaScript中,将对象用作属性键是什么意思?

我已在Chrome / Node和Firefox中进行了测试。


2
目前 JavaScript 不支持将对象作为键,它可能会被强制转换为字符串,因此存储的值将是 [object Object],从而使每个对象都返回 true 作为键。但在未来,您可以使用“Map”来将对象作为键进行存储。 - Sushil
听起来很有趣,@Sushil。你有关于这个潜在的未来地图类的信息参考吗?我搜索了几分钟后没有找到任何提及它的地方。 - Drew Noakes
1
这是ECMAScript 6的未来实现 https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Map,此外还有一个非常好的WeakMap概念(我个人很喜欢)https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/WeakMap,您可以在这里阅读相关信息。 - Sushil
规范:属性访问器使用表达式键评估属性访问转换为属性键。属性键通过保留符号值或将值强制转换为字符串而获得。 - Sebastian Simon
规范:属性访问器使用表达式键进行属性访问评估转换为属性键。属性键可以通过保留符号值或将值强制转换为字符串来获得。 - undefined
2个回答

12

在JavaScript中将对象用作属性的键意味着该对象将首先被强制转换为字符串,因为JavaScript对象只允许字符串键。

具体来说,为什么在c中查找b会返回存储在a属性中的值?因为{a: 1}{b: 2}的字符串表示都是"[object Object]",因此属性被覆盖。

编辑:如果您确实需要使用对象作为键(如果可能,我建议选择另一种解决方案),则可以使用对象的JSON表示形式:

c[JSON.stringify(a)] = 1
c[JSON.stringify(b)] = 2

但是,再次尝试考虑不同的方法。也许这些对象除了对象本身之外还有唯一的标识符。


1
谢谢Linus,这很有道理。我确实需要在某种意义上使用对象作为键,因此一个实际的Map类会很有用。但是我的集合中不会有太多这样的对象,所以我想我只需创建一个键/值对数组,并在“获取”时通过循环遍历它们,使用===测试键。这将是O(N),但我的N大约为10,所以我不介意。再次感谢。 - Drew Noakes

2
当您使用对象作为键时,键变成了object.toString()的结果,即[Object Object]
因此,您所做的是将一个值设置为属性"[Object Object]",并通过属性"[Object Object]"获取该值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接