一些需要注意的数据类型:
- NaN的数据类型是
number
- Array、Date、null的数据类型是
object
- 未定义变量的数据类型是
undefined
自动转换类型:尝试操作一个 "错误" 的数据类型时,会自动转换为 "正确" 的数据类型。
5 + null // 返回 5 null 转换为 0
"5" + null // 返回"5null" null 转换为 "null"
"5" + 1 // 返回 "51" 1 转换为 "1"
"5" - 1 // 返回 4 "5" 转换为 5
==
运算符的隐式类型转换规则
1.类型转换:两个操作数的类型不同,js会尝试转换成相同的类型。
2.原始类型比较:两个操作数的类型都是原始类型(如数组、字符串、布尔值),它们会被转换成相同的类型,再进行比较。
3.null
和undefined
比较:被视为相等。
4.字符串和数字比较:js会将字符串转换成数字,再进行比较。如果字符串不能转换成有效的数字,则结果为false
。
5.布尔值比较:一个是布尔值,一个非布尔值,则布尔值会被转换成数字,再进行比较。true
为1,false
为0。
6.对象和原始类型比较:对象通过ToPrimitive
转换成原始类型,再进行比较。通常涉及到对象的valueOf()
和toString()
方法。
ToPrimitive(obj, Number) ==> Number({})
//1.如果 obj 是基本类型,直接返回
//2.否则,调用 valueOf 方法,如果得到原始值,则返回
//3.否则,调用 toString 方法,如果得到原始值,则返回
//4.否则,报错
7.NaN
比较:NaN
与任何值比较都返回false
,包括NaN
自己。
在写代码时,最好使用===
来避免隐式类型转换并确保类型和值都相等。
[] == ![]返回true
关系转换图如下:
[]
与![]
都是对象,!
的优先级大于==
,要先进行非运算。
!
会进行两步操作:
- 1.对
!
后面的操作数转换成布尔值 - 2.将这个布尔值取反
则将[]
转换成布尔值,根据官方文档可知,任何对象转换成布尔值都是true
,所以![]
为false
。
则原式变为[] == false
,一个是对象一个是布尔值,则都会转换成数字进行比较。[]
经过ToPrimitive
会被转换成字符串""
。再将等号两边的字符串""
和布尔值false
转换成数字 0
,得到 0 == 0
,打印得到 true
。
//执行过程
[] == ![]
[] == !true // 将空数组这个对象类型转换成布尔值
[] == false // ! 运算符对 true 进行取反
'' == false // 对 [] 进行 ToPrimitive 操作,返回一个空对象
0 == 0 // 将等号两边都转换成数字类型
字符串转换成数字
js在将字符串转换成数字时,它会查看字符串的内容。如果表示一个有效的数字则会转换成数字,不是则转换成NaN
。
Q:\t == 0
是为什么?
- 有些特殊含义的字符会被转换成数字0,
\t \n \r
在进行字符串转换数字时都是0。 - 还有种说法是:字符串在
toNumber()
时会首先去除空格,再判断该数字是否为非数字。如果NaN
,则结果为``NaN;如果字符串为空则结果为0。
可以多看看这张图:
下图是使用不同的值转换为数字,字符串,布尔值: