本文將介紹一段使用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"
但願你們看的開心!若是本文有什麼錯誤或者不嚴謹的地方,歡迎在評論區留言。