我分配了以下三个变量:
const a = {key:true}
const b = {key:false}
const c = {[a]:'1',[b]:'2'}
当我尝试将以下内容登录到控制台时:
console.log(c[a],c[b])
我得到了以下内容:
2 2
我以为我应该得到:
1 2
我为什么错了,我该如何解决?
答案 0 :(得分:9)
对象只能将字符串(或符号)作为其键。如果您尝试使用非字符串,它将被转换为字符串。因此,当您将c[a]
设置为1
时,a
是一个对象,这意味着它需要转换为字符串。因此,您最终将c["[object Object]"]
设置为1。然后,当您设置c[b]
时,您会做同样的事情,再次转换为"[object Object]"
,从而覆盖已经存在的值。
尝试注销c
来查看此内容:
const a = {key:true}
const b = {key:false}
const c = {[a]:'1',[b]:'2'}
console.log(c);
需要使用对象作为键是不寻常的,但是如果需要,可以使用Maps代替对象
const a = {key:true}
const b = {key:false}
const c = new Map();
c.set(a, '1');
c.set(b, '2');
console.log(c.get(a));
console.log(c.get(b));
答案 1 :(得分:4)
我为什么错了,我该如何解决?
对象属性名称将转换为字符串(如果它们不是字符串或符号)。默认情况下,对象值序列化为[object Object]
,因此对于JavaScript,两个值都相同:
const a = {key:true}
const b = {key:false}
console.log('a', a.toString());
console.log('b', b.toString());
1。。您可以实现自己的toString
方法来将对象序列化为独特的字符串:
function toString() {
return this.key.toString();
}
const a = {key:true, toString}
const b = {key:false, toString}
const c = {[a]:'1',[b]:'2'}
console.log(c[a],c[b])
但这不会让您恢复用作键的原始值(您可以可以使用对象的JSON表示作为键,您可以将其转换回对象,但是仅在“关键对象”仅包含可以用JSON表示的值的情况下有效。
2。。您可以使用Map
代替对象,该对象允许将任意值用作键:
const a = {key:true}
const b = {key:false}
const c = new Map([[a, '1'], [b, '2']]);
console.log(c.get(a),c.get(b))
请注意,Map
使用对象标识来查找值,因此c.get({key: false})
将不起作用。
哪种方式真正取决于您的需求。
答案 2 :(得分:2)
您可能会看看c
,在那里您看到a.toString()
的结果
const a = { key: true }
const b = { key: false }
const c = { [a]: '1', [b]: '2' }
console.log(c);
console.log(c[a], c[b]);
为解决此问题,您可以使用JSON字符串
const a = { key: true }
const b = { key: false }
const c = { [JSON.stringify(a)]: '1', [JSON.stringify(b)]: '2' }
console.log(c);
console.log(c[JSON.stringify(a)], c[JSON.stringify(b)]);
尤其对于对象作为键,可以使用WeakMap
:
const a = { key: true }
const b = { key: false }
const c = new WeakMap([[a, '1'], [b, '2']]);
console.log(c.get(a), c.get(b));
答案 3 :(得分:1)
JavaScript对象键是字符串(或者可选地是Symbols,但这既不是这里也不是那里)。如果您使用console.log(c),您会看到它是{[object Object]:“ 2”},因为[a]和[b] .toString()都是“ [object Object]”
至于“修复”……我不明白您要实现的目标,抱歉,我无法为您提供帮助。