使用JavaScript隱式類型轉換輸出"nb"

本文將介紹一段使用JavaScript隱式類型轉換輸出"nb"的代碼,並講解具體的轉換過程。segmentfault

預備知識

請先閱讀文章ECMAScript7規範中的ToPrimitive抽象操做數組

代碼

([][[]]+[])[+!![]]+([]+{})[!+[]+!![]] // "nb"

轉換過程

咱們分四部分講解具體的轉換過程:lua

  1. ([][[]]+[])
  2. [+!![]]
  3. ([]+{})
  4. [!+[]+!![]]

([][[]]+[])

  1. [],一個空數組;
  2. [[]],緊跟在數組後面的[的語義應該是表示屬性操做,相似於obj[key][]的做用,而不是表示數組。這個裏面,既然外層的[]表示獲取屬性的運算符,裏面的[]確定就表示key了。由於key是原始數據類型,因此會調用ToPrimitive抽象操做把[]轉化爲原始數據類型,也就是空字符串"",因此上面兩個結合起來就是:code

    var a = []
    var b = []
    a[b] // => a[""] => undefined
  3. +,相加操做;
  4. [],空對象,和上面的步驟結合起來就是:對象

    undefined + []

    相加操做會把操做符兩邊的操做數經過ToPrimitive抽象操做轉化爲原始數據類型,也就是[]會變爲""ip

    undefined + ""

    相加操做的抽象步驟中,若是有一個操做數是字符串,會調用ToString抽象操做把兩個操做數都轉化爲字符串類型,也就是:字符串

    undefined + "" // => "undefined" + "" => "undefined"

綜上,([][[]]+[])的結果就是字符串"undefined"get

[+!![]]

  1. !![],表示把一個數據轉化爲布爾類型,由於[]是一個真值,因此!![]的結果是true
  2. +!![],表示把前面的結果轉化爲數字類型,也就是+truetrue轉化爲數字是1,因此+!![]的結果是1
  3. [+!![]],也就是[1],結合第一部分([][[]]+[])的結果:it

    ([][[]]+[])[+!![]] // => "undefined"[1] => 也就是獲取字符串"undefined"的第二個字符,也就是"n" => "n"

([]+{})

相加操做會調用ToPrimitive抽象操做把操做符兩邊的數據轉化爲原始數據類型,也就是:io

([]+{}) // => "" + "[object Object]" // => "[object Object]"

[!+[]+!![]]

  1. +[],把數組轉化爲數字:

    +[] // => +"" => 0
  2. !+[],也就是!0true
  3. !![]true
  4. !+[]+!![],也就是true + true,又是相加操做,由於操做符兩邊都是布爾類型,因此會轉化爲數字類型,也就是1 + 1,也就是2

第三部分和第四部分的結果結合起來就是:

([]+{})[!+[]+!![]] // => "[object Object]"[2] => 也就是取字符串"[object Object]"的第三個字符,也就是"b" => "b"

第一二部分和第三四部分結合起來的結果就是:

([][[]]+[])[+!![]]+([]+{})[!+[]+!![]] // => "n" + "b" => "nb"

總結

但願你們看的開心!若是本文有什麼錯誤或者不嚴謹的地方,歡迎在評論區留言。

相關文章
相關標籤/搜索