话不多说,先来看一个“表达式”:

{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 调了半个小时