Javascript 对象、花括号和冒号
话不多说,先来看一个“表达式”:
{a:1}[123]
猜猜结果?
结果是:
[123]
这个问题不难,但是其中有很多坑,甚至导致半个小时调不出一个bug。
冒号和花括号在Javascript中的作用网上多有文章记载,这里这个表达式之所以能正确解析,是因为将冒号视作了 Label
,而且基于优先级,将花括号视作了 复合语句 的标记。那么最后结果是[123]
也就不稀奇了,引擎自动为复合语句结束补充了一个分号,毕竟在js里面,分号是可以省略的。
那么其他问题呢?
比如说,我在一个函数传参的时候使用了这样一个"表达式" (严格来讲这已经不是一个表达式了,因为其中被一个不存在的分号分隔开来了)
那么我们直接在外面包一个括号,将其作为语句执行,结果是这样的:
({a:1}[123]) === "undefined" //true
这个结果是比较出人意料的,我只能解释成 js引擎在解析的时候,语法树中明明是一个表达式,结果却被补充了一个分号,导致无法正确的解析从而返回了一个 "undefined",这么说的话,简单一点, ({}[1])
也应该是 "undefined"。事实也正是如此。
那么这个坑会有什么影响呢?举个栗子,你在传参的时候,使用对象字面量表达式,后面又跟了一个数组字面量表达式,如果恰好漏了一个逗号,那么原本应该接收到的参数,就变成了一个undefined,偏偏这又不会报错,从语法分析上来讲,所有的语句都是合法的。
function log(...args){
console.log("收到的参数有:",...args)
}
log({a:1}[123],"123")
// 输出: 收到的参数有: undefined 123
别问,问就是今天下午调这个 bug 调了半个小时