JavaScript强制类型转换补充
前面的关于强制类型的介绍基本可以认为是显式的强制类型转换,因为那些都是我们知道的东西。对于这篇补充,需要解释下面的现象,下面基本都是隐式的强制类型转换:
一、加法
//1.字符串和数字(把数字变成强制转换成)
"1" + 2 //=>12
1+"2" //=>12
//2.布尔值和数字(把布尔值强制转换成数字)
1 + true //=>2
true + 1 //=>2
//3.null和数字
1 + null //=>1
null + 1 //=>1
//4.undefined和数字 (把undefined强制转换成数字,undefined转换的结果是NaN)
2 + undefined //=>NaN
undefined + 2 //=>NaN
//后面不一一举例了,下面列出一个引用的情况
[0] + 1 //=>"01"
Array.prototype.valueOf = function(){return true}
[0] + 1 //=>2
//下面是比较奇怪的例子
{} + 100 //=>100
{a:''} + 100 //=>100
{'a':''} + 100 //报错
总结(再次强调 var a = new Number(1),a会被看成是引用类型处理):
1.如果遇到Symbol直接报错
2.如果遇到引用类型,那么先将引用类型转换成基本类型 (这样一来全都是基本类型)
3.如果有操作数是string类型,那么都转换成string相加
4.如果没有string,那么都转换成number相加(NaN也是number类型,它加任何number都是NaN)
二、条件判断
条件判断似乎没有这么多的规矩,直接将这些转换成布尔值就完事了。这里需要注意的是|| 和 &&操作符在JavaScript中不同的地方。|| 操作会首先将其左边的操作转换成布尔值,如果为true就返回这个操作数 。如果为false就会返回右边的操作数。&&刚好相反,这个操作会首先将其左边的操作转换成布尔值,如果为true就返回它右边操作数,如果为false就返回左边的 。需要注意的是,这两个操作符返回的不是布尔值,是操作数!!!
//常见的例子
var a,b
if(true || (a=2)){} //=> a的值是undefined
if(false || (a=2)){} //=> a的值是2
if(false && (b=2)){} //=>b的值是undefined
if(true && (b=2)){} //=> b的值是2
//不常见的例子
var a = a || "默认值" //如果a没有定义,那么a的值就是默认值,这样也不是特别严谨
windiw.work && work() //如果work函数已定义,那么就执行它,需要注意的是假设work函数return的是false,那么整个表达式的值就是false
Boolean(windiw.work && work()) //假设work没有返回值,那么结果就是false
三、== 和 === 的区别
==比较时允许强制类型转换,而 === 不允许。
//1.数字和字符串比较(将字符串强制转换成数字然后再比较)
1 == "1" //true
1 == "true" //false
0 == "" //true
//2.布尔类型和其他类型的比较(首先将布尔类型转换成数字,再比较)
1 == true //true
2 == true //false
"1" == true //true
["1"] == true //true
true == ["0"] //false
//很奇怪现象
"2" == true //false
"2" == false //false
//3. null和undefined
null == "" //false
null == 0 //false
null == false //false
null == "null" //false
undefined == "" //false
undefined == 0 //false
undefined == false //false
undefined == "undefined " //false
null == undefined //true
//4.NaN,NaN与任何变量的结果都是false
NaN == NaN //false
//5.引用和非引用的比较(首先将引用类型转换成基本类型,然后比较)
//6.引用类型和引用类型的比较
new Number(1) == new Number(1) //=>false
总结:
1.如果2边都是引用类型不会发生强制类型转换,因为都是地址,可以直接比较。
2.遇到引用先valueOf...变成基本类型。(这样一来全都是基本类型的比较了)
3.如果遇到Symbol或者NaN,直接false
4.null只能等于undeifned(这样一来就是number,string,boolean了)
5.遇到布尔值先转数字。(这样一来就是number,string)
6.如果是数字和字符串,先把字符串转换成数字(这样就是number和number的比较了)注意:Symbol和NaN不等于任何东西
//比较极端的例子
[] == ![] //=>true
//首先![]中!会先将[]强制转换成布尔值true,然后!true的结果是false,。原式等价于[] == false
//然后按照比较规则 [] 转换成基本类型 "" 原式等价于 "" == false
//再然后 false 转换成 0 原式等价于 "" == 0
//最后"" 转换成Number ,原式等价于 0 == 0 返回true
//比较少见的例子
0 =="\n" //=>true
Number('\n') //=>0
四、大小比较
//1.数字和其他 (将其他转化成数字)
10 < "11" //true
10 < "9" //false
1 > null //true
1 > undefined //false
1 > [0]
//2.引用类型和基本类型 (将引用类型转换成基本类型)
//3.
//2.引用和引用
[1] > [1] || [1] == [1] //false
[1] >= [1] //true
[1] <= [1] //true
总结:
1.如果有Symbol则报错
2.如果有NaN则返回false
3.如果是引用和引用,则将引用转换成基本类型
4.如果是引用和非引用,则将引用转换成基本类型(这样变成了基本类型和基本类型的比较)
5.如果是全都是string,则按位比较字母的大小。
6.否则,将双方转化成number再比较。