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

基本
  1. 装箱操作: 就是将基本类型(String, Number, Boolean)转为引用类型
  2. 拆箱操作: 与装箱相反,就是将引用类型转为基本类型, 常用的基本方法有: 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";

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

从一道题看js的拆箱操作的更多相关文章

  1. 再谈C#装箱和拆箱操作

    1. 使用非泛型集合时引发的装箱和拆箱操作 看下面的一段代码: 1 2 3 4 5 6 7 8 var array = new ArrayList(); array.Add(1); array.Add ...

  2. java 中的自动装箱和拆箱操作

    在前面的文章中提到,Java为每种基本数据类型都提供了对应的包装器类型,至于为什么会为每种基本数据类型提供包装器类型在此不进行阐述,有兴趣的朋友可以查阅相关资料.在Java SE5之前,如果要生成一个 ...

  3. JS里面的装箱和拆箱操作

    平日工作里,我想各位少侠对下面的用法都不陌生吧 var s1 = "abc"; var s2 = s1.indexOf("a") 还有例如什么indexOf() ...

  4. Java自动装箱和自动拆箱操作

    1.Java数据类型 在介绍Java的自动装箱和拆箱之前,我们先来了解一下Java的基本数据类型. 在Java中,数据类型可以分为两大种,Primitive Type(基本类型)和Reference ...

  5. javascript中的装箱和拆箱操作

    1,装箱: 把基本数据类型转换为对应的引用类型的操作称为装箱,把引用类型转换为基本的数据类型称为拆箱. 在<javascript高级程序设计>中有这样一句话: 每当读取一个基本类型的时候, ...

  6. java和c#中的装箱和拆箱操作

    c#装箱和拆箱 装箱:整体上来说,装箱是将值类型转换成引用类型,比如将Vector3转换成Object类型. 具体而言: 1)在托管堆中为值类型分配内存.除了原始的数值以外还应该有指向该数值的引用. ...

  7. Java暗箱操作之自动装箱与拆箱

    我以前在写Android项目的时候,估计写得最多最熟练的几句话就是: List<Integer> list = new ArrayList<Integer>(); list.a ...

  8. 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱

    引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并 ...

  9. 转 C# 装箱和拆箱[整理]

    1.      装箱和拆箱是一个抽象的概念 2.      装箱是将值类型转换为引用类型 :拆箱是将引用类型转换为值类型       利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的 ...

随机推荐

  1. opacity兼容性问题

    用来设定元素透明度的 Opacity 是CSS 3里的一个属性.当然现在还只有少部分浏览器支持. 不过各个浏览器都有自己的私有属性来支持,其中包括老版本的Mozilla和Safari: IE: fil ...

  2. 小学四则运算口算练习app---No.2

    经过昨天的了解,虽然还是很懵,总要下手摸到鼠标来写第一个页面! 这是一开始设置出体数目和时间的页面,使用者根据提示进行相关设置即可! 代码如下: <?xml version="1.0& ...

  3. opencv4.0.0+cmake编译(含contrib)

    https://blog.csdn.net/bobo184/article/details/88749651 前言笔者环境:win10+vs2015+cmake3.8.2 介绍下4.0.0的新特性,沿 ...

  4. 如何关闭/禁用.NET JIT调试对话框

    当.NET程序有未处理的异常时,您可能会希望关闭出现的调试对话框.下面有两个选项: 1.启用JIT调试的注册表项 对于包含托管代码的应用程序,公共语言运行库将显示类似于JIT附加调试器的对话框.控制此 ...

  5. selenium--操作JS弹框

    前戏 我们常见的弹框有三种,一种是alert弹框,一种是prompt弹框,还有一种是confirm弹框那他们有什么不同呢?不同点就是他们长的不一样,alert弹框有一段文字和一个确定按钮,如下 在来看 ...

  6. 深入js系列-类型(显式强制转换)

    什么是显式 这里的显式和隐式是以普遍的标准来进行讨论的,你能看出来是怎么回事,那么它对你是"显式",相反你不知道的话,对你就是"隐式" 抽象操作 字符串.数字. ...

  7. centos 升级openSSH7.81

    1.下载相关依赖包 [root@Log ~]# yum install -y gcc openssl-devel pam-devel rpm-build 2.下载安装包 wget http://ftp ...

  8. iptables 表和链的对应关系

    filter表 主要用于对数据包进行过滤,根据具体的规则决定是否放行该数据包(如DROP.ACCEPT.REJECT.LOG).filter 表对应的内核模块为iptable_filter,包含三个规 ...

  9. shell 字符串拼接

    #!/bin/bash name="Shell" url="http://c.biancheng.net/shell/" str1=$name$url #中间不 ...

  10. ECMAScript6-2

    1.模板字串.箭头函数 1.1.模板字串 传统js,输出模板 var str='<b>姓名:</b>'+ '<span>lxr</span>'; con ...