被方括号引用搞懵逼了

2021-10-28 15:56:47 +08:00
 teslayun
var foo = {unique_prop: 1}, bar = {unique_prop: 2}, object = {};
object[foo] = 'value';
console.log(object[bar]);

原文:上述的代码的输出也是 "value",由于对象 foo 和 bar 都会被转成相同的字符串。在 SpiderMonkey JavaScript 引擎中,这个字符串是 "[object Object]"。

这是啥原理。。。

查方括号引用的时候看见的一个例子, https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Property_Accessors

2814 次点击
所在节点    JavaScript
15 条回复
murmur
2021-10-28 15:59:15 +08:00
不是,这东西除了面试,真的有人用么,想输出就老老实实的自己写序列化,或者就 json.stringify ,java 开发也没人直接把 object 扔 logger 里打印把
murmur
2021-10-28 16:00:26 +08:00
哦,记错考点了,你这个得用 WeakMap ,这个 key 是可以用对象的
Kasumi20
2021-10-28 16:01:10 +08:00
什么什么意思,因为你访问的是 foo.[object Object] 啊
yaphets666
2021-10-28 16:01:46 +08:00
原理就是引擎内部对这种特殊情况做了处理呗,js 里面好多类似的。
对象和数组不是一回事。数组的 a 是指向 a[0],但是对象没有这种逻辑啊。
mxT52CRuqR6o5
2021-10-28 16:01:50 +08:00
object 的 key 是 string ,所以 object[foo]约等于是 object[foo.toString()]
kevin1
2021-10-28 16:03:12 +08:00
对象在用作 key 时被自动转化成了"[object Object]",因为普通对象的 key 只能是 String 。所以其实当你访问 obj[foo]时,实际上是在访问 obj["object Object"]。
kop1989
2021-10-28 16:05:53 +08:00
你观察 object 的结构就会发现。一个对象的字段名,是可以为[object Object]的,无论是 object[foo]还是 object[bar]你对应的都是 object.[object Object](伪代码)。
jtwor
2021-10-28 16:06:51 +08:00
6 对的
teslayun
2021-10-28 16:08:04 +08:00
@murmur #1, 这种方括号引用还是有用的吧,比如必须使用变量来访问属性的时候
murmur
2021-10-28 16:09:27 +08:00
@teslayun 一般的 map key 是字符串,方括号那个用法不是
var a = {
[dynamicKey]: 'value'
}
这种写法么
拿 object 做 key ,要么是 weakmap 的高端用法,要么是开发或者面试故意留的坑
teslayun
2021-10-28 16:11:55 +08:00
@kop1989
@kevin1
@mxT52CRuqR6o5 明白了,感谢大佬,普通对象的 key 只能是 String ,对象用 key 的时候被 toString()了,那么,上面这个,如果打印 object[object]应该也是一样的输出“value”
kop1989
2021-10-28 16:13:25 +08:00
@murmur #9 一般情况下就是单纯的留的坑,就跟问 Integer 5 == Integer 5 返回 true 还是 false 一样。反问一句面试官这玩意的用意是什么,对方估计也就是吃瘪或者背个官话。

@teslayun #10 赵本山:“恭喜你都会抢答了~”
teslayun
2021-10-28 16:20:17 +08:00
@murmur 不是哦,比如计算数组中元素出现的次数,弄成对象属性
const list = ["a", "b", "c", "a", "a"];

const countedList = list.reduce(function (acc, cur) {
if (cur in acc) {
acc[cur]++;
} else {
acc[cur] = 1;
}
return acc;
}, {});
console.log(countedList);

// {a: 3, b: 1, c: 1}
tsanie
2021-10-28 17:23:28 +08:00
@teslayun 捉一个虫,cur in acc 要写成 acc.hasOwnProperty(cur),否则源数组里一旦有个'constructor', 'toString'之类的元素就要出错辣

或者{}改成 Object.create(null)
noe132
2021-10-28 18:44:34 +08:00
https://262.ecma-international.org/5.1/#sec-11.2.1
第六步,对属性名是执行了 ToString 内部逻辑的。普通对象 ToString 的结果最后的逻辑是调用了 valueOf ,valueOf 调用了 toString 方法,结果就是一个"[object Object]"字符串。

如果想让对象作为 key ,建议使用 Map 。Map 可以用对象作为 key 来存储数据。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/811291

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX