为什么object [bar]与object [foo]具有相同的输出?

时间:2018-07-03 11:35:43

标签: javascript

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]);
     

由于foobar都被转换为相同的字符串,因此它也输出“值”。在SpiderMonkey JavaScript引擎中,该字符串为"['object Object']"

但是,我无法理解关于对象[bar]等于“值”的原因的解释...您能给出更好的解释吗?

1 个答案:

答案 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来做到这一点。