为什么 ++[[]][+[]]+[+[]] === "10"

初看到这个表达式的时候,一脸懵逼,这是什么玩意。。。实际上这个表达式没有任何问题,可以运行,也可以得出结果。下面我们就来分析分析。

第一眼看到这个表达式是完全搞不清的。不过没关系,我们先将它拆解一下。

++[[]][+[]]+[+[]]

==>

++[[]][+[]]
+
[+[]]

现在分为两个部分 ++[[]][+[]] 和 [+[]]。这时我们能看出来一个最基本的组成部分 +[]。它的值是多少呢?这里我们需要了解一下 + 这个一元操作符的原理。

一元操作符 + / - 操作对象为非 Number 类型时,会调用Number() 函数进行转型。String 类型会按一定规则转成 Number类型,Object 类型会先后调用  valueOf() 和 toString(),再尝试调用 Number()。

贴上《Javascript 高级程序设计》上面的截图:

知道了 + 的逻辑,现在我们再分析 +[] 的结果。首先 [] 是一个对象,会先后调用 valueOf() 和 toString(),调用 valueOf() 的结果为 [],调用 toString() 的结果为 "",此时的结果是 "",然后再调用 Number(),结果为 0。

所以 +[] 的结果就是 0。

那么我们继续简化上面的表达式。

++[[]][+[]]
+
[+[]]

==>

++[[]][0]
+
[0]

==>

++[]
+
[0]

现在结构已经很简单了,我们现在再来分析 ++[] 的结果。其实一元操作符 ++ 和 + 很像,也会去转换它要操作的对象,所以 [] 会被转换成 0,++0 的结果就是 1。

++[]
+
[0]

==>

1
+
[0]

现在的结果已经很清楚了,如果加性操作符 + 的两边存在非 Number 类型,那么就会将两边转换成 String 类型然后连接。所以最后的结果就是:

1
+
[0]

==>

1
+
"0"

==>

"10"