JavaScript属性访问器为何支持包含单个属性名的任意嵌套数组?兼析部分嵌套访问失效的逻辑
这个问题的核心在于JavaScript处理对象属性访问器中非字符串/非Symbol键的转换规则,尤其是数组作为键时的行为。让我们一步步拆解背后的逻辑:
核心规则:键的字符串转换
当你使用obj[key]这种方括号语法访问属性时,JavaScript会自动将key转换为字符串(如果key不是Symbol类型)。对于数组来说,这个转换是通过调用Array.prototype.toString()实现的——这个方法会递归地把数组的每个元素转成字符串,再用逗号把它们拼接起来。
举几个关键的转换例子:
["last"].toString()→"last"[[["last"]]].toString()→"last"(每一层都是单元素数组,递归转换后结果还是内层元素的字符串值)[ [], ["last"] ].toString()→"" + "," + "last"→",last"(空数组的toString()结果是空字符串)[ [[]], ["last"] ].toString()→"" + "," + "last"→",last"
你的“能正常运行且得到目标值”的情况
这些案例的共同点是,数组最终转换成的字符串恰好是"last",完美匹配source的属性:
source[srcKeys]:srcKeys是["last"],直接转成"last",所以能拿到"Capulet"。source[[[[srcKeys]]]]:不管嵌套多少层单元素数组,每一层的toString()结果都是内层元素的字符串值,最终整个数组转成"last",自然能访问到目标属性。
你的“能正常运行但返回undefined”的情况
这些代码本身没有语法错误(所以能正常运行),只是数组转成的字符串不是"last",source里没有对应的属性,所以返回undefined:
source[[],[[[srcKeys]]]]:数组是[ [], [[["last"]]] ],转成字符串是",last",source没有这个键,返回undefined。source[[[]],[],srcKeys]]:转成",,last",同样找不到对应属性,返回undefined。
你认为“无法正常运行”的情况
其实这些代码本身是可以正常执行的(不会抛出错误),只是同样返回undefined而已——因为它们的数组转成的字符串也不是"last":
source[[[],[[srcKeys]]]]:数组是[ [ [], [["last"]] ] ],内层数组转成",last",整个数组的字符串也是",last",找不到对应属性。- 另外两个案例同理,转成的字符串分别是
",,last"和",last",都不匹配"last"属性,所以返回undefined。
总结
只要数组递归调用toString()后得到的字符串正好等于对象的某个属性名,就能访问到对应的值;反之,就会返回undefined(如果没有这个属性)。只有当嵌套数组是单元素结构(每一层都只有一个元素,最终指向["last"])时,转成的字符串才会是"last",其他包含多个元素或空数组的情况,都会生成带逗号的字符串,自然匹配不到目标属性。
内容的提问来源于stack exchange,提问作者smac89
相关产品推荐
相关产品推荐

