在JavaScript中,如果key是一个对象,为什么object[key]不等于key?
我测试了上面的代码,得到在JavaScript中,如果key是一个对象,为什么object[key]不等于key?,javascript,Javascript,我测试了上面的代码,得到false。如果我尝试console.log(c[a]==b),则会打印true 为什么?这里的问题与如何设置对象的键有关。发件人: 参数 nameValuePair1,nameValuePair2。。。nameValuePairN 名称(字符串)和值(任意值)对,其中名称与值之间用冒号分隔 值 任何价值 可以通过三种方式访问对象的值(通过相应的键): var a = new Object; var b = new Object; var c = new Obje
false
。如果我尝试console.log(c[a]==b)
,则会打印true
为什么?这里的问题与如何设置
对象的键有关。发件人:
参数
nameValuePair1,nameValuePair2。。。nameValuePairN
- 名称(字符串)和值(任意值)对,其中名称与值之间用冒号分隔
值
- 任何价值
可以通过三种方式访问对象的值(通过相应的键):
var a = new Object;
var b = new Object;
var c = new Object;
c[a] = a;
c[b] = b;
console.log(c[a] === a);
使用括号表示法时,需要注意括号之间的间隙!对象使用该方法设置它们的键和值,除非传递给它们一个字符串(那么toString
)就没有意义了。使用点表示法时,他们使用.key
作为键
让我们看看您的案例:
var o = {};
var key = "fun";
// method 1:
o[key] = "the key will be equal to `key.toString()"
// method 2:
o.key = "the key will be equal to 'key'"
// method 3:
o["key2"] = "the key will be equal to `key2`"
/*
{
"fun" : "the key will be...", // method 1
"key" : "the key will be...", // method 2
"key2": "the key will be..." // method 3
}
*/
我尝试了一点,royhowie可能是对的。正如您在这个实现中看到的,我切换了赋值的顺序,然后c[a]==a给出了一个true
var a = {}
, b = {}
, c = {}
;
c[a] = a;
// `a` is not a string, and we're using brackets, so the key
// will be equal to `key.toString()`:
// a.toString() === "[object Object]"
// Try the following in your console: `{}.toString()`
// Note how this is different from console.log({}), since
// the console exposes your object (that's why the dev console is useful)
// c is now: `{ "[object Object]" : a }`
c[b] = b;
// b is also an object, so `b.toString()` is the same as `a.toString()`
// that means c is now `{ "[object Object]" : b }`
assert c[a] === a
// a.toString() == b.toString() == "[object Object]"
// and we just noted that c was `{ "[object Object]" : b }`
// so of course this is false
assert c[b] === b
// true because c[b] == b;
assert c["[object Object]"] === b;
// also true
assert c.b === b
// false, since `c` has no "b" key (c.b is `undefined`)
输出:true对象不是JavaScript对象的有效键,只有字符串是有效的
因此,当您这样做时:
var a = new Object;
var b = new Object;
var c = new Object;
//I switched the following lines of code
c[b]=b;
c[a]=a;
console.log(c[a]===a);
编译器不能像在c[a]或c[b]中那样使用a或b作为c的键
但是,它不会失败,因为JavaScript可以解决这个问题。首先它发现
变量是一个对象,并且
该变量具有toString-函数
因此,JavaScript编译器将调用每个变量的toString()。默认情况下,Object.prototype.toString它将返回“[Object Object]”-string,因为实现是执行该操作的默认实现,该值将成为新的键
c[a] = a;
c[b] = b;
这不是你想要的。问题是toString在默认情况下将始终返回相同的值,因此assigments将始终指向相同的键
为了证明toString实际上是个问题,您可以实际执行一个可怕的欺骗,使每个对象返回唯一的字符串
c["[object Object]"] = a;
c["[object Object]"] = b; // overrides the previous
在此之后,c[a]的键将是c[“Object1”],c[b]的键将是c[“Object2”],依此类推。。。c[a]==a和c[b]==b的工作原理与预期一致,但在现实生活中,这并不是一个好的解决方案
解决这个问题的一个可接受的方法是使用其他一些键,可能是分配给对象的ID,比如c[a.ID]=a,或者使用ES6映射对象,其中任何值(包括对象)都可以用作键
映射对象是一个简单的键/值映射。任何值(对象和对象)
基本值)可以用作键或值
你为什么要这样做?@VikashKesarwani-这是个好问题。很可能他把问题简化成一个简单的例子,它不像你在C++中所做的那样,这里是分配问题。对于这种你想做的自我披露的形式,没有解决方案c.a=a
或c['a']=a
。这是用来设置属性名的,就像给它一个字符串一样c[a]
将属性名称设置为与变量a
的值相同。console.log(c)密码>谜团解开了。这个问题很平常。正如我在上面的评论中提到的,自我披露的作业注释不是a.toString()
字符串“[object object]”
?@slebetman您是对的;我在想JSON。我将修复这个问题(尽管这是同一个概念)@2pha您将要执行的c['[object]]={}
,这将使c
数组保持不变,因为您是通过字符串而不是索引访问它的。@2pha我重写了我的答案,并试图使其更简洁。你写的东西正是发生的。是的,你的切换使情况完全不同。谢谢。现在这个问题更清楚了,但我仍然不知道如何使用你推荐的c[a.id]。这取决于你的意图,但如果你想从“哈希”c中查找对象,你可以为每个对象分配一些唯一的id,like obj.id=1234;然后将该值赋值为c,类似于c[obj.id]=obj;然后,如果要从散列中查找对象,请使用c[]或c[someObject.id]等进行搜索。
// don't do this!!!
(function() {
var id=1;
Object.prototype.toString = function() {
if(!this._id) this._id = id++;
return "Object"+this._id;
}
}());