数据类型之间的转换
首先我们要知道,在 JS 中类型转换只有三种情况,分别是:
- 转换为布尔值
- 转换为数字
- 转换为字符串
1、转boolean
在条件判断时,除了 undefined, null, false, ‘’, NaN, 0, -0,其他所有值都转为 true,包括所有对象。
2、转number
在条件判断时,会比较==/===两边的值是否相等,这里会隐式转换成nubmer然后再去进行比较。
下图可以看出:
- 0的情况有:null、’’、false、[]
- NaN的情况有: undefined、非数字内容的字符串(‘asda’)、对象({})、非空非单一数值类型的数组([1,2])
3、转string
- 数组转string,[1,2,3] => ‘1,2,3’
- 对象转string,‘[object,object]’
- 其余的都可以正常转为string类型且内容不会变
4、对象转原始类型
对象在转换类型的时候,会调用内置的 [[ToPrimitive]] 函数,对于该函数来说,算法逻辑一般来说如下:
- 如果已经是原始类型了,那就不需要转换了
- 调用
x.valueOf()
,如果转换为基础类型,就返回转换的值 - 调用
x.toString()
,如果转换为基础类型,就返回转换的值 - 如果都没有返回原始类型,就会报错
当然你也可以重写 Symbol.toPrimitive
,该方法在转原始类型时调用优先级最高。
let a = {
valueOf() {
return 0
},
toString() {
return '1'
},
[Symbol.toPrimitive]() {
return 2
}
}
1 + a // => 3
5、四则运算符
加法运算符不同于其他几个运算符,它有以下几个特点:
- 运算中其中一方为字符串,那么就会把另一方也转换为字符串
- 如果一方不是字符串或者数字,那么会将它转换为数字或者字符串
1 + '1' // '11'
true + true // 2
4 + [1,2,3] // "41,2,3"
如果你对于答案有疑问的话,请看解析:
- 对于第一行代码来说,触发特点一,所以将数字
1
转换为字符串,得到结果'11'
- 对于第二行代码来说,触发特点二,所以将
true
转为数字1
- 对于第三行代码来说,触发特点二,所以将数组通过
toString
转为字符串1,2,3
,得到结果41,2,3
另外对于加法还需要注意这个表达式 'a' + + 'b'
'a' + + 'b' // -> "aNaN"
因为 + 'b'
等于 NaN
,所以结果为 "aNaN"
,你可能也会在一些代码中看到过 + '1'
的形式来快速获取 number
类型。
那么对于除了加法的运算符来说,只要其中一方是数字,那么另一方就会被转为数字
4 * '3' // 12
4 * [] // 0
4 * [1, 2] // NaN
6、比较运算符 ==
对于 ==
来说,如果对比双方的类型不一样的话,就会进行类型转换
假如我们需要对比 x
和 y
是否相同,就会进行如下判断流程:
-
首先会判断两者类型是否相同。相同的话就是比大小了
-
类型不相同的话,那么就会进行类型转换
-
会先判断是否在对比
null
和undefined
,是的话就会返回true
-
判断两者类型是否为
string
和number
,是的话就会将字符串转换为number
1 == '1' ↓ 1 == 1
-
判断其中一方是否为
boolean
,是的话就会把boolean
转为number
再进行判断'1' == true ↓ '1' == 1 ↓ 1 == 1
-
判断其中一方是否为
object
且另一方为string
、number
或者symbol
,是的话就会把object
转为原始类型再进行判断'1' == { name: 'yck' } ↓ '1' == '[object Object]'
注意!
- undefiend和null,自身比较和相互比较的时候为true,其余跟任何数据类型比较都为false
- NaN not a number 自身比较的时候也不相等比如 :‘abc’ 不是一个数字 ‘def’也不是一个数字
- infinity 表示为无穷大,自身比较为true, -infinity 表示为负无穷大,两者比较为false
7、!和!!转换
js中 ! 的用法是比较灵活的,它除了做逻辑运算常常会用!做类型判断,可以用!与上对象来求得一个布尔值,
1、!可将变量转换成boolean类型,null、undefined和空字符串取反都为true,其余都为false,主要是用来判空
!null=true
!undefined=true
!''=true
!100=false
!'abc'=false
2、!!常常用来做类型判断,在第一步!(变量)之后再做逻辑取反运算,这其实不好理解,其实就是强制的转为boolean类型
在条件判断if中其实没比较使用
!!a ==Boolean(a)
一般这样写hasName == name? true : false,换种写法hasName = !!name