你可能见到过这样的情况:”5” - 3 == 2和”5” + 3 == “53”,可是这是为什么呢?
上节提到过关于强制类型转换到的概念,通过调用方法来实现数据在不同类型间的转换。同样的,既然有强制类型转换,那么也会有隐式类型转换。
隐式类型转换
转换为数字类型进行比较运算。以下几种情况会有数据的默认转换:
isNaN()
翻译过来意思就是:是NaN吗?此方法会先调用Number()的方法将数据转化为数字类型来进行比较。
数字类型包括四个值:具体的数字,NaN,Infinity,-Infinity
如果转换为数字时,返回的值刚好是NaN,则调用isNaN()时返回true。
具体步骤为:isNaN(demo) => Number(demo) => NaN => true / false
1 | isNaN(23) //false |
当调用Number()数据是怎么转换的,可以参考上一篇(强制类型转换)。Number(null)值为0
++/- -, +/-
++ / - - 分为前置++和后置++,区别在于变量的输出顺序不同。
+/- 为一元正负运算符,并不是通常所说的数学中的加和减。即+4, -3
1 | +3 //3 |
1 | var str = 'a'; |
算数运算符
‘+ , - , * , / , % (取余) ‘会将符号两边的值转换为数字进行运算
1 | null + 1 //1 |
需要注意的是: + 号遇到字符串时,相当于字符串的拼接,他会把加号另外一边不是字符串的值转化为字符串,并和已知的字符串进行拼接。
如果没有字符串时,则将 + 两边的值正常转换为数字类型来进行计算。
1 | 2 + "" //"2" |
空串””和空格字符串” “的区别在于其布尔值,空串””为false,空格字符串” “为true
逻辑运算符
‘ &&(与) , ||(或) , !(非) ‘输出运算结果。运算结果为真实的值
(1) && (2):找到假为止。他会先取出(1)表达式的值,看是否为真。
(1)为真,继续执行(2),不管(2)结果为真还是为假都输出(2)表达式的运算结果。
(1)为假,输出(1)表达式的运算结果。
(1) || (2):找到真为止。他会先取出(1)表达式的值,看是否为真。
(1)为真,输出(1)表达式的运算结果。
(1)为假,继续执行(2),不管(2)结果为真还是为假都输出(2)表达式的运算结果。
!(1):取反。(1)运算结果为真时,取反则为假。(1)为假,取反为真。
1 | 1 && 2 //2 |
比较运算符
‘ > , < , >= , <= , == , != ‘比较结果为布尔值
1 | 1 == "1" //true |
字符串和数字比较时,会将字符串转化为数字进行比较。字符串比较时,比较的为ASCII值。
根据undefined和null的特殊性质(undefined和null不等于0,不大于0,不小于0),所以让他们两个相等。
NaN不等于任何值,包括他自身。
不发生类型转换
===(绝对等于) , !==(绝对不等于)1
21 == "1" //true
1 === "1" //false
小练习
1 | 11 + "11" //"1111" |
1 | var str = "abc"; |
包装类。强行给原始值加上某个属性时可以加上,但是实际访问时并不存在。所以if的条件并不成立,即不能给test加上sign属性。
1 | var str = false + 1; |
有赋值和比较运算符时,先比较后赋值。即false != 1, 比较运算符,输出结果为布尔值。
1 | typeof typeof(undefined); //"string" |
1 | if (typeof(a) && -true + (+undefined) + "") { |
typeof(a)返回值为”undefined”,数据类型为字符串,为真。接着逻辑运算符后面的代码,-true + (+undefined) + “” => -1 + NaN + “” => NaN + “” => “NaN”,为字符串类型,为真,执行if里面的条件语句。
1 | if (11 + "11" * 2 == 33) { |
1 | [3 < 1 < 2, 1 > 2 > 3]; //[true, false] |
当有多个比较运算符时,从左到右两个值一起进行比较,并将第一次比较的结果和第二次比较运算符右边的值作比较。
3 < 1 < 2比较时就是先让3和1比,3 > 1,所以第一个比较的结果返回false(0),然后再让0和后面的2比,0 < 2, 所以比较结果为真,返回true。
也就是3 < 1 < 2 => 0(false) < 2 => true