MDN在其属性访问器页面上具有以下内容: 以下链接提供了有关javascript的Property_accessors的描述, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors
var foo = {unique_prop: 1}, bar = {unique_prop: 2}, object = {}; object[foo] = 'value'; console.log(object[bar]);
由于
foo
和bar
都被转换为相同的字符串,因此它也输出“值”。在SpiderMonkey JavaScript引擎中,该字符串为"['object Object']"
。
但是,我无法理解关于对象[bar]等于“值”的原因的解释...您能给出更好的解释吗?
答案 0 :(得分:4)
您的报价开始得太早了,这部分:
由于将类型1强制转换为“ 1”,因此将输出“值”。
与它上面的代码 相关,而不是它下面的代码。
对您的问题:
JavaScript属性名称始终是字符串或符号。该代码显示"value"
,因为当您使用 object 作为属性名称时,该对象将隐式转换为字符串,就像您在其上使用String(obj)
一样,将普通对象不管其内容如何,都强制转换为字符串"[object Object]"
。因此,无论您使用foo
还是bar
,它都是相同的属性名称。
所以这个:
var foo = {unique_prop: 1};
var bar = {unique_prop: 2};
var object = {};
object[foo] = 'value';
console.log(object[bar]);
与此相同:
var foo = {unique_prop: 1};
var bar = {unique_prop: 2};
var object = {};
object[String(foo)] = 'value';
console.log(object[String(bar)]);
以及String(foo)
和String(bar)
都产生相同的字符串"[object Object]"
:
var foo = {unique_prop: 1};
var bar = {unique_prop: 2};
console.log("String(foo) =", String(foo));
console.log("String(bar) =", String(bar));
如果要将对象用作键,则需要使用Map
。示例:
var foo = {unique_prop: 1};
var bar = {unique_prop: 2};
var map = new Map;
map.set(foo, 'value');
console.log(map.get(bar)); // undefined
console.log(map.get(foo)); // "value"
如果您不能使用地图,请使用该对象的某些唯一属性。
因为不可避免地有人会向您建议它:您可以使用JSON.stringify
为该对象创建一个字符串,但这不是一个好主意。一方面,如果有多个属性,那么它就很脆弱,因为JSON中的属性顺序将取决于属性的名称和添加它们的顺序。为什么不应该使用JSON.stringify
的示例:
// Don't do this
var foo = {unique_prop: 1, another_prop: 2};
var object = {};
object[JSON.stringify(foo)] = "value";
console.log(object[JSON.stringify(foo)]); // "value" - so far so good
var bar = {another_prop: 2, unique_prop: 1};
console.log("foo.unique_prop = " + foo.unique_prop);
console.log("bar.unique_prop = " + bar.unique_prop);
console.log("foo.another_prop = " + foo.another_prop);
console.log("bar.another_prop = " + bar.another_prop);
// Seemingly the same object, so this should work, right?
console.log(object[JSON.stringify(bar)]); // undefined
// It doesn't because:
console.log("JSON.stringify(foo) = ", JSON.stringify(foo));
console.log("JSON.stringify(bar) = ", JSON.stringify(bar));
.as-console-wrapper {
max-height: 100% !important;
}
从ES2015开始,对象中自己的属性具有顺序,并且在创建字符串时需要JSON.stringify
遵循该顺序。因此最好不要通过JSON.stringify
来做到这一点。