本文将介绍一段使用JavaScript
隐式类型转换输出"nb"
的代码,并讲解具体的转换过程。segmentfault
请先阅读文章ECMAScript7规范中的ToPrimitive抽象操做。数组
([][[]]+[])[+!![]]+([]+{})[!+[]+!![]] // "nb"
咱们分四部分讲解具体的转换过程:lua
[]
,一个空数组;[[]]
,紧跟在数组后面的[
的语义应该是表示属性操做,相似于obj[key]
中[]
的做用,而不是表示数组。这个里面,既然外层的[]
表示获取属性的运算符,里面的[]
确定就表示key
了。由于key
是原始数据类型,因此会调用ToPrimitive
抽象操做把[]
转化为原始数据类型,也就是空字符串""
,因此上面两个结合起来就是:code
var a = [] var b = [] a[b] // => a[""] => undefined
+
,相加操做;[]
,空对象,和上面的步骤结合起来就是:对象
undefined + []
相加操做会把操做符两边的操做数经过ToPrimitive
抽象操做转化为原始数据类型,也就是[]
会变为""
:ip
undefined + ""
相加操做的抽象步骤中,若是有一个操做数是字符串,会调用ToString
抽象操做把两个操做数都转化为字符串类型,也就是:字符串
undefined + "" // => "undefined" + "" => "undefined"
综上,([][[]]+[])
的结果就是字符串"undefined"
。get
!![]
,表示把一个数据转化为布尔类型,由于[]
是一个真值,因此!![]
的结果是true
;+!![]
,表示把前面的结果转化为数字类型,也就是+true
,true
转化为数字是1
,因此+!![]
的结果是1
;[+!![]]
,也就是[1]
,结合第一部分([][[]]+[])
的结果:it
([][[]]+[])[+!![]] // => "undefined"[1] => 也就是获取字符串"undefined"的第二个字符,也就是"n" => "n"
相加操做会调用ToPrimitive
抽象操做把操做符两边的数据转化为原始数据类型,也就是:io
([]+{}) // => "" + "[object Object]" // => "[object Object]"
+[]
,把数组转化为数字:
+[] // => +"" => 0
!+[]
,也就是!0
:true
;!![]
,true
;!+[]+!![]
,也就是true + true
,又是相加操做,由于操做符两边都是布尔类型,因此会转化为数字类型,也就是1 + 1
,也就是2
;第三部分和第四部分的结果结合起来就是:
([]+{})[!+[]+!![]] // => "[object Object]"[2] => 也就是取字符串"[object Object]"的第三个字符,也就是"b" => "b"
第一二部分和第三四部分结合起来的结果就是:
([][[]]+[])[+!![]]+([]+{})[!+[]+!![]] // => "n" + "b" => "nb"
但愿你们看的开心!若是本文有什么错误或者不严谨的地方,欢迎在评论区留言。