从(++[[]][+[]]+[+[]]) 等于10了解隐式转换
本篇博客主要是对 关于在表单下拉选择中blur与click冲突解决
背景
++[[]][+[]]+[+[]]==='10'如果把这段表达式拆分开来,它相等于
++[[]][+[]]
+
[+[]]思路
在 JavaScript 里,+ === 0 是完全正确的。 + 会把一些字符转化成数字,在这里,这个式子会变成 +""或 0。因此,我们可以简化一下(++ 比 + 有更高的优先级):
++[[]][0]
+
[0]因为 [[]]0 的意思是:获取 [[]] 的第一个元素,这就得出了下面的结果: ● [[]]0 返回内部数组 ()。根据语言规范,我们说 [[]]0 === 是不正确的,但让我们把这个内部数组称作 A,以避免错误的写法。 ● ++[[]]0 == A + 1, 因为 ++ 的意思是”加一”。 ● ++[[]]0 === +(A + 1);换句话说,你得到的永远是个数值( +1 并不一定得到的是个数值,但 ++一定是)。 同样,我们可以把这一堆代码简化的更清晰。让我们把 A 换回成 :
+([] + 1)
+
[0]在 JavaScript 里,这也是正确的: + 1 === "1",因为 == "" (这相当于一个空的数组的内部元素连接),于是
+([] + 1) === +("” + 1),并且
+("” + 1) === +("1"),并且
+("1") === 1 让我们再次简化一下:
1
+
[0]同样,在 Javascript 里,这是正确的:0 == "0",因为这是相当于一个有一个元素的数组的内部元素的连接。 各元素会使用,分隔。 当只有一个元素时,你可以推论出这个过程的结果就是它自身的第一个元素。 所以,最终我们得到 (数字 + 字符串 = 字符串):
1
+
"0"
=== "10" //原因
首先我们需要知道什么是隐式转换,JavaScript是一门弱类型的语言,他在声明变量的时候不需要指定类型,对变量赋值也没有类型的检测,所以js是非常的灵活的,但是有时候也会出现一些非常匪夷所思的问题, 隐式类型转换就是指,数据的类型在不用人工干预的情况下进行转换的行为。在js中,当运算符在运算时,如果两边数据不统一,CPU就无法计算,这时我们编译器会自动将运算符两边的数据做一个数据类型转换,转成一样的数据类型再计算。这种无需程序员手动转换,而由编译器自动转换的方式就称为隐式转换 方式 隐式转换主要有三种方式
将值转为原始值,ToPrimitive()。
将值转为数字,ToNumber()。
将值转为字符串,ToString()。运算符中的隐式类型转换
+、-、*、/、++、–、+=、-=、>、<、>=、<=、==、!= 这些运算中,系统都会将值先转换为数字类型再进行计算或比较。 1、加号运算符( + )可以把任何数据类型转换为数字,转换规则与 Number() 方法相同。 Null、Undefined 和 false在与数字的计算中折算为0,true 折算为1。 undefined会被转换为 NaN。 NaN在算术运算符中遇到任何值进行比较结果都为NaN。 比如
console.log(1+'true'); //'1true'
console.log(1+true); //2
console.log(1+null); //1
console.log(1+undefined); //NaN2、可以用加号运算符很方便的把其他类型的值转换为数字类型。
console.log(+true); //1
console.log(+undefined); //NaN
console.log(+"123"); //123
console.log(+"string"); //NaN3、除了加号运算符,也可以使用 a - 0 的形式,将数据类型转换为数字。
console.log(11-'5'); //6
console.log('11'-'5'); //6
console.log(-null); //-0
console.log(true - 0); //1
console.log(null - 0); //0
console.log("123" - 0); //123
console.log("" - 0); //0
console.log([999] - 0); //999
console.log([2] - [1]); //14、比较运算符(= =),== 不同于===,故也存在隐式转换。
比较运算符会把其他数据类型转换number数据类型后再比较。 在javascript中有两种特殊情况无视规则。 复杂数据类型的隐式转换 复杂数据类型在隐式转换时的顺序如下:
- 先试用 valueOf() 方法获取其原始值,如果原始值不是 number 类型,则使用 toString() 方法转换成 string 类型。
- 将 string 类型转换成 number 类型进行运算。 比如
console.log([1,2]=='1,2'); //true将 1,2 用 valueOf() 取其原始值,发现不是数字类型,转换成 string 类型之后,发现与 ‘1,2’ 相等,所以返回 true。因此在js空数组等于0,空数组的toString()方法会得到空字符串,而空对象的toString()方法会得到字符串object Object, 通过同String()转成空字符串,再通过Number()转成0。因此+等于0。