从一道题看js的拆箱操作
前段时间看到一道题,如下:([][[]]+[])[+!![]]+([]+{})[!+[]+!![]]问最终打印结果,然后简单了解一下js的装箱,拆箱操作。
基本
- 装箱操作: 就是将基本类型(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";
通过上面的题目,应该已经大致了解了关于拆箱的一些基础了。这样,下次看到就不会一头雾水了。
从一道题看js的拆箱操作的更多相关文章
- 再谈C#装箱和拆箱操作
1. 使用非泛型集合时引发的装箱和拆箱操作 看下面的一段代码: 1 2 3 4 5 6 7 8 var array = new ArrayList(); array.Add(1); array.Add ...
- java 中的自动装箱和拆箱操作
在前面的文章中提到,Java为每种基本数据类型都提供了对应的包装器类型,至于为什么会为每种基本数据类型提供包装器类型在此不进行阐述,有兴趣的朋友可以查阅相关资料.在Java SE5之前,如果要生成一个 ...
- JS里面的装箱和拆箱操作
平日工作里,我想各位少侠对下面的用法都不陌生吧 var s1 = "abc"; var s2 = s1.indexOf("a") 还有例如什么indexOf() ...
- Java自动装箱和自动拆箱操作
1.Java数据类型 在介绍Java的自动装箱和拆箱之前,我们先来了解一下Java的基本数据类型. 在Java中,数据类型可以分为两大种,Primitive Type(基本类型)和Reference ...
- javascript中的装箱和拆箱操作
1,装箱: 把基本数据类型转换为对应的引用类型的操作称为装箱,把引用类型转换为基本的数据类型称为拆箱. 在<javascript高级程序设计>中有这样一句话: 每当读取一个基本类型的时候, ...
- java和c#中的装箱和拆箱操作
c#装箱和拆箱 装箱:整体上来说,装箱是将值类型转换成引用类型,比如将Vector3转换成Object类型. 具体而言: 1)在托管堆中为值类型分配内存.除了原始的数值以外还应该有指向该数值的引用. ...
- Java暗箱操作之自动装箱与拆箱
我以前在写Android项目的时候,估计写得最多最熟练的几句话就是: List<Integer> list = new ArrayList<Integer>(); list.a ...
- 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并 ...
- 转 C# 装箱和拆箱[整理]
1. 装箱和拆箱是一个抽象的概念 2. 装箱是将值类型转换为引用类型 :拆箱是将引用类型转换为值类型 利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的 ...
随机推荐
- css 布局 一中一右
.container { position: relative; .my-center { text-align: center; line-height: 30rpx; min-width: 400 ...
- Java中HTTP网络传输中文编码问题
Java中HTTP网络传输中文编码问题 1.java中new String(str.getBytes("utf-8"),"iso-8859-1")编码详解 前提 ...
- ABP 从core降到级.net framework
后台: Application层得先写接口 再写实现,不然 abp.services.app 这个里面就没有该service.并且service保留的接口,就是interface里面定义的接口. 文件 ...
- uname 命令简介
[root@localhost root]# uname --help Usage: uname [OPTION]... Print certain system information. With ...
- c++功能与方法笔记
1. windows判断创建目录 #include <Shlwapi.h> #pragma comment(lib, "shlwapi.lib") //windows ...
- java线程池源码的理解
线程池 新建线程和切换线程的开销太大了,使用线程池可以节省系统资源. 线程池的关键类:ThreadPoolExecutor. 该类中包含了大量的多线程与并发处理工具,包括ReentrantLock.A ...
- 【Maven插件】exec-maven-plugin
<plugin> <artifactId>exec-maven-plugin</artifactId> <groupId>org.codehaus.mo ...
- 您访问的URL地址不被允许。
访问一个网站在一定时间内的频率过高会被当做攻击网站的行为,然后会被该网站限制访问,再次访问该网站便会出现以下界面,解决办法有: ①更改自己电脑的IP地址 ②换一个设备访问,比如把用电脑访问换成用手机访 ...
- 【转】Selenium 报错:Element is not clickable at point的解决办法
天一同学在写Selenium Java脚本时遇到一个问题,登录进入系统之后,要点击左侧的一个菜单,但是执行到该语句时报下面的错误: Firefox中报错如下:org.openqa.selenium.E ...
- golang gin 上传图片到aws s3
要上传图片到aws s3首先需要 知道 aws 的地区 也就是region ,还需要知道储存桶的名字,其次就是Access key ID和Secret access key package handl ...