将对象用作贴图时,其键始终转换为字符串。为什么?

时间:2016-06-10 13:53:10

标签: javascript dictionary ecmascript-6

以下代码:

let user1={name: "Sam"};
let user2={name:"Tyler"};
let totalReplies={};
totalReplies[user1]=5;
totalReplies[user2]=42;
console.log(totalReplies[user1]);
console.log(totalReplies[user2]);

生成输出:

42
42

我希望输出为:

5
42

阅读,我得到了'当使用对象作为地图时,其键始终转换为字符串'。我不确定我是否理解这意味着什么或为什么对象键被转换为字符串。 无论哪种方式,理解输出为42 42的原因应该有助于实施这一概念。

4 个答案:

答案 0 :(得分:5)

JavaScript对象仅支持字符串和符号作为键。

在这种情况下,JS会将对象强制转换为字符串值(类似于[object Object])。

所以基本上你的代码就相当于:

let user1={name: "Sam"};
let user2={name:"Tyler"};
let totalReplies={};
totalReplies['[object Object]']=5;
totalReplies['[object Object]']=42;
console.log(totalReplies['[object Object]']);
console.log(totalReplies['[object Object]']);

您可以在此处详细了解强制: http://webreflection.blogspot.ch/2010/10/javascript-coercion-demystified.html

<强>解决方案

如果您需要在ES6 +中使用对象作为键,则可以使用Maps而不是对象作为数据存储:

let user1={name: "Sam"};
let user2={name:"Tyler"};
let totalReplies = new Map();
totalReplies.set(user1, 5);
totalReplies.set(user2, 42);
console.log(totalReplies.get(user1));
console.log(totalReplies.get(user2));

答案 1 :(得分:2)

根据ECMAscript standard,对象属性名称可以是标识符名称(即标识符+保留字),字符串文字数字文字

在你的情况下user1user2是对象,并转换为字符串,它们返回"[object Object]"这解释了你的输出。

如果您想使用对象(或任何原始值)作为地图密钥,您可以使用 ES6标准中包含的原生Map object

答案 2 :(得分:0)

totalReplies[user1]=5表示totalReplies[{name: "Sam"}]=5,这没有任何意义。键始终是字符串,而不是对象。

您想要totalReplies[user1.name]=5;

答案 3 :(得分:0)

他们实际上是:

var ob = {};
console.log(ob.toString())// prints "[object Object]"

每个对象的方法toString是执行的,结果是相同的[object Object],因为您要添加两次相同的键,所以分配的索引会被新值覆盖。