【JS】JavaScript的隐式类型转换详解
详解js的隐式转换以及哪些场景下会触发隐式转换,以及一些使用小技巧
一、JavaScript中的数据类型
简单数据类型(原始类型): String Number Boolean undefined null Symbol(ES6新增,用于表示独一无二的值,因为是原始类型,创建时不需new)
引用数据类型(复杂数据类型): Object(Object、Array、Function本质上都是Object)
二、什么是隐式转换
当运算符在运算时,若两端数据类型不统一
,编译器会帮我们自动转换
成相同类型
的数据,这就是隐式转换。
三、隐式转换规则
隐式转换是一步一步完成的,如果比较或运算的过程中数据类型仍不一致,最终会将两边数据都转成Number类型再进行运算。
转换步骤:
Object => String => Number
Boolean => Number
undefined/null => Number
四、什么情况下会发生隐式转换
当运算符两端的数据类型不一致,会触发隐式转换
1. +运算符
+可以拼接字符串 也是算术运算符
Number只有当与Number、Boolean、null、undefined+时,才是算术运算符
拼接字符串
非字符串数据先调用String()转成字符串 再进行拼接
对象toString()后为[object Object]
,第一个o小写,第二个大写
数组toString()
-
Number + String
console.log(1+"测试") // "1测试"
-
Boolean + String
console.log(true+"测试") // "true测试"
-
null + String
console.log(null+"1") // null1
-
undefined + String
console.log(undefined+"1") // undefined1
-
Array + String
console.log([1,2,3]+"测试") // 1,2,3测试
-
Object + String
console.log({name:"田本初"}+"测试") // [object Object]测试
-
Function + String
const fn = () => { console.log("111") } console.log(fn+"测试") // () => { // console.log("111") // }测试
两个非String数据拼接 均变为String 再进行拼接
算术运算符
非Number数据先调用Number()转成数字 再进行运算
Boolean中true为1,false为0
Null强制转换后为0
-
Boolean + Number
console.log(1 + true) // 2 console.log(1 + false) // 1
-
Null + Number
console.log(1 + null) // 1
-
Undefined + Number
console.log(1 + undefined) // NaN
2. -运算符
与+运算符基本一致,需注意当与引用类型+
时是看做字符串的拼接
,但是-运算符只会视为计算,故与引用类型-
时,只会返回NaN
3. ==运算符
为什么不能用===?
=== 判断两边数据是否全等
,即数据类型与值
均相等,而隐式转换是在两者数据类型不同时才触发的。
而 == 只判断值
是否相等
==两边均为引用数据类型时
返回false
,因为引用数据类型比较的是地址
console.log([] == []) // false
console.log([] == {}) // false
console.log({} == {}) // false
const fn = () => {
console.log("111")
}
console.log(fn == []) // false
console.log(fn == {}) // false
引用类型比较
只有长度小于1
的数组
才有可能
转为Number,长度0(空数组) => “” => 0,[1] => “1” => 1
而Function与Object最终不会转成纯Number只能为NaN
-
与Boolean比较
根据
隐式转换规则
Object => String => Number Boolean => Number 二者根据Number进行比较// [] => "" => 0 // true => 1 // 故为false console.log([] == true) // false
-
与String比较
Object => String 此时与字符串类型一致 不必继续将二者转为Number 就可直接比较
// [1,2] => "1,2" console.log([1,2] == "1,2") // true
-
与Number比较
Object => String => Number 需注意:
数组长度
只要大于1
,最终结果就为NaN
// [1] => "1" => 1 console.log([1] == 1) // true // [] => "" => 0 console.log([] == 0) // true // 需注意 [1,2] => "1,2" => NaN 而不是12 console.log([1,2] == 12) // false
基本数据类型比较
其中NaN
较为特殊,js规定它与任何数据比较均为false
,包括其本身
-
String 与 Number
// "1" => 1 console.log('1' == 1) // true
-
Boolean 与 String
// true => 1 // "1" => 1 console.log(true == "1") // true
-
Boolean 与 Number
// true => 1 console.log(true == 1) // true
-
undefined
console.log(undefined == undefined) // true
-
null
console.log(null == null) // true
-
undefined 与 null
console.log(undefined == null) // true
-
NaN
console.log(NaN == NaN) // false console.log(NaN == 1) // false // ...js规定 全都是false
4. >运算符
<运算符同理
-
String 与 Number
// "11" => 11 console.log("11" > 10) // true
-
String 中的内容为Number
// "11" => 11 // "1" => 1 console.log("11" > "1") // true
-
String 中的内容为字母、符号等编码
若为等长字母
console.log("a" > "b") // false
若为不等长字母,比较同位置字母大小,直至做出判断
console.log("ab" > "b") // false console.log("abc" > "abb") // true
符号同理,都是根据ACSII码进行判断
console.log("@" > "!") // true console.log("@!" > "@@") // false
5. !取反
技巧: !!连续两次取反可以将非布尔值转成布尔值
console.log(!![]) // true
console.log(!![]) // true
console.log(!!0) // false
console.log(!!1) // true
6. 语句中的判断条件也会触发隐式转换
依旧根据隐式转换规则 按序转换
true、1 被视为 true
false、“”、0、null、undefined、NaN 被视为 false
总结
类型相同
基本类型,直接比较值
引用类型,比较指针
类型不同
如果两边类型不同,则两边都尝试转成number类型。
对于引用类型,先调用valueOf(),如果能转成数字,则进行比较。
不能转成数字就调用toString()方法转成字符串。
null、NaN、undefined单独一套规则
null、NaN、undefined和string、number、boolean、object类型比较时,都不做隐式转换,比较的结果直接为false。
console.log(NaN==NaN) //false
console.log(undefined==null) //true
console.log(null==null) //true
console.log(null==undefined) //true
console.log(undefined==undefined) //true
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)