使用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"

总结

但愿你们看的开心!若是本文有什么错误或者不严谨的地方,欢迎在评论区留言。

相关文章
相关标签/搜索