前段时间看到一道题,如下:([][[]]+[])[+!![]]+([]+{})[!+[]+!![]]问最终打印结果,然后简单了解一下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. Django+uWSGI+Nginx 部署网站

    Django 1.11设置 保证Django在本地调试没有问题: 当然这是前提^_^ 收集静态文件至指定文件夹 Django静态文件设置具体参考:https://docs.djangoproject. ...

  2. 洛谷 p2055 假期的宿舍 题解

    好长时间没更博客了 因为实在太蒻了 这让本蒟蒻怎么办 今天终于遇到了一道模板题(之前也有,不过太蒻了都不会) 不过...写代码5分钟,调试2小时 分界线:回归正题 这个就是普通的匈牙利算法 差不多 思 ...

  3. CSS3实现PS中的蚁行线动画以及画布的马赛克背景图

    话不多说,先看例子,外链 效果截图如下: 蚁行线 马赛克背景 代码: 蚁行线代码如下: /* <!-- HTML代码 --> <div class="ant"&g ...

  4. docker compose yml 文件常用字段简介

    常用参数: version # 指定 compose 文件的版本 services # 定义所有的 service 信息, services 下面的第一级别的 key 既是一个 service 的名称 ...

  5. Elasticsearch运维经验总结

    Elasticsearch运维经验总结 2018年12月10日 16:38:41 运小白 阅读数 3811   版本说明:5.6.4(要严格注意ES及其插件.第三方工具的版本匹配关系) 系统负载:(日 ...

  6. Python3.7 - Argparse模块的用法

    argparse 是一个命令行参数解析模块. argparse 是python自带的命令行参数解析包,可以用来方便地读取命令行参数,当你的代码需要频繁地修改参数的时候,使用这个工具可以将参数和代码分离 ...

  7. 解决Spring和SpringMVC扫描注解类的冲突问题

    原文地址:https://blog.csdn.net/xiaobao5214/article/details/52042041 最正确的配置方式:在主容器中applicationContext.xml ...

  8. Linux内核device结构体分析

    1.前言 Linux内核中的设备驱动模型,是建立在sysfs设备文件系统和kobject上的,由总线(bus).设备(device).驱动(driver)和类(class)所组成的关系结构,在底层,L ...

  9. fio压测

    目录 fio工具介绍 参数介绍 测试举例 模板如下: 四路服务器测试的小tips fio工具介绍 用于测试存储设备IO性能. 当存储设备中存在用户数据时,严谨使用fio进行写操作!!! 参数介绍 rw ...

  10. Lua函数声明与调用

    lua编程中,我们经常也会遇到函数的声明定义和调用. [1]lua中函数定义与调用的方法 lua有两种函数定义和调用的方法(本质都是用属性,方式不同而已): (1)点号形式 (2)冒号形式 两种方法的 ...