从一道题看js的拆箱操作_莺呼_前端开发者

前段时间看到一道题,如下:([][[]]+[])[+!![]]+([]+)[!+[]+!![]]问最终打印结果,然后简单了解一下js的装箱,拆箱操作。

基本
  1. 装箱操作: 就是将基本类型(String, Number, Boolean)转为引用类型
  2. 拆箱操作: 与装箱相反,就是将引用类型转为基本类型, 常用的基本方法有: valueof , toString()
  • 装箱操作: 就是将基本类型(String, Number, Boolean)转为引用类型
  • 拆箱操作: 与装箱相反,就是将引用类型转为基本类型, 常用的基本方法有: valueof , toString()
  • 分析

    像上面的那个题目,主要是拆箱操作,下面就来简单拆解分析一下吧:

       1. 基础:
        [] ==> [] (Array);
        [[]] ==> [array(0)]  (Array);
        []+[[]] ???
        ok, 我们简单来了解一下js中的+运算符:
        +:一般是用于对象相加的,这是在两个对象都是Number的情况下。那其他类型下就涉及到隐式转换,下面看下隐式转换的规则
          1. 如果一个对象是String,那么就要将另一个对象转换为String再进行字符串拼接
          2. 如果对象都是复杂类型,那么就要将两个对象均转化为String,再进行拼接。
          至于如果对象是其他简单类型(Number, Boolean),就要先将对象转化为Number再进行运算
        所以 []+[[]] ==> String([]) + String([[]]) == "" + "" ==> ""
       2. 拆解:
        然后我们来看下题目,简单拆分为4部分:
        
          1. ([][[]]+[])
             [][[]] 这部分乍一眼看过去会觉得很蒙,但我们已经知道[] ==> Array,常用的获取Array中的数据的方法有Array[]
             所以,让我们来拆解下吧:
             首先为了更清楚,将最左侧的[]赋值给 father ==> var father = [];
             将右侧[]中的[]赋值给child ==> var child = [];
             即最终 [][[]] == father[child] == "undefined"
             [][[]] + [] == String("undefined") + String([]) == "undefined"
             
          2. [+!![]]
             关于这一部分,我们需要了解一下!!
             !!: 一般来说,似乎大家普遍认为是将对象取反,再取反,即双重否定。但其实应该是将对象强制转换为Boolean类型。
             关于Boolean中,需要关注,{}和[]转换为Boolean时是true.
             [+!![]] ==>[+true] ==> [Number(true)] ==> [1]
          3. ([]+{})
             这一部分就很简单了: []+{} ==> String([]) + String({}) == "" + "[object Object]".
             但是,如果将上面两个对象调转位置呢:
             {} + [] : 按常规来说,应该是和上面一样的结果,但是最终的打印结果却是0,这是为什么呢。
             js中{} 不仅可以代表一个对象,同时也有可能是一个代码块,有些时候,js会将写在前面的{}解释为代码块,于是参与运算的其实就只有+[]了。
          4. [!+[]+!![]]
            经过上面部分,这里也很清楚了:
            !+[] ==> ! + String([]) == !+"" == !"" == true
            [true + !![]] == [true + true] = [Number(true) + Number(true)] == [2]
          
          所以最后的结果: "undefined"[1] + "[object Object]"[2] == "nb";
    

    1. 基础:
    [] ==> [] (Array);
    [[]] ==> [array(0)] (Array);
    []+[[]] ???
    ok, 我们简单来了解一下js中的+运算符:
    +:一般是用于对象相加的,这是在两个对象都是Number的情况下。那其他类型下就涉及到隐式转换,下面看下隐式转换的规则
    1. 如果一个对象是String,那么就要将另一个对象转换为String再进行字符串拼接
    2. 如果对象都是复杂类型,那么就要将两个对象均转化为String,再进行拼接。
    至于如果对象是其他简单类型(Number, Boolean),就要先将对象转化为Number再进行运算
    所以 []+[[]] ==> String([]) + String([[]]) == "" + "" ==> ""
    2. 拆解:
    然后我们来看下题目,简单拆分为4部分:

    1. ([][[]]+[])
    [][[]] 这部分乍一眼看过去会觉得很蒙,但我们已经知道[] ==> Array,常用的获取Array中的数据的方法有Array[]
    所以,让我们来拆解下吧:
    首先为了更清楚,将最左侧的[]赋值给 father ==> var father = [];
    将右侧[]中的[]赋值给child ==> var child = [];
    即最终 [][[]] == father[child] == "undefined"
    [][[]] + [] == String("undefined") + String([]) == "undefined"

    2. [+!![]]
    关于这一部分,我们需要了解一下!!
    !!: 一般来说,似乎大家普遍认为是将对象取反,再取反,即双重否定。但其实应该是将对象强制转换为Boolean类型。
    关于Boolean中,需要关注,{}和[]转换为Boolean时是true.
    [+!![]] ==>[+true] ==> [Number(true)] ==> [1]
    3. ([]+{})
    这一部分就很简单了: []+{} ==> String([]) + String({}) == "" + "[object Object]".
    但是,如果将上面两个对象调转位置呢:
    {} + [] : 按常规来说,应该是和上面一样的结果,但是最终的打印结果却是0,这是为什么呢。
    js中{} 不仅可以代表一个对象,同时也有可能是一个代码块,有些时候,js会将写在前面的{}解释为代码块,于是参与运算的其实就只有+[]了。
    4. [!+[]+!![]]
    经过上面部分,这里也很清楚了:
    !+[] ==> ! + String([]) == !+"" == !"" == true
    [true + !![]] == [true + true] = [Number(true) + Number(true)] == [2]

    所以最后的结果: "undefined"[1] + "[object Object]"[2] == "nb";

    通过上面的题目,应该已经大致了解了关于拆箱的一些基础了。这样,下次看到就不会一头雾水了。

    » 本文来自:前端开发者 » 《从一道题看js的拆箱操作_莺呼_前端开发者》
    » 本文链接地址:https://www.rokub.com/73574.html
    » 您也可以订阅本站:https://www.rokub.com
    赞(0)
    64K

    评论 抢沙发

    评论前必须登录!