目录
JavaScript是一种弱数据类型语言 ,在JavaScript中定义变量不需要提前指定变量类型,变量的数据类型是在程序运行过程中由JavaScript引擎动态决定,因而可以使用同一个变量来存储不同类型的数据(var、let、const),这也意味着它会自动转换值的数据类型,以便数据之间更加容易相互比较和操作。除去我们比较熟知的显式转换,JavaScript中的隐式转换更加需要理解和一定的经验。下面将为大家详细的列举一下JS隐式转换的各种情况。
在JavaScript中,数据类型的隐式转换主要有三种情况:
- 转换为number类型
- 转换为boolean类型
- 转换为string类型
JavaScript隐式类型转换通常发生在以下情况:
- 当使用不同类型的值进行操作时(数字和字符串)
- 当使用相等或不等运算符(== 或 !=)进行比较时
- 当对一个非布尔类型的值进行布尔运算时(if语句或逻辑运算符)
JavaScrip隐式转换规则
JavaScript中隐式类型转换的机制是比较复杂的,涉及到了数据类型、操作符、运算顺序等多方面的因素。
当两个操作数具有不同的类型时,系统内部根据一系列规则来决定将其转换为相同的类型,这些规则包括:
- 如果一个操作数是数字,则将另一个操作数转换为数字
- 如果一个操作数是字符串,则将另一个操作数转换为字符串
- 如果一个操作数是布尔值,则将另一个操作数转换为布尔值
- 如果一个操作数是对象,则尝试将另一个操作数转换为对象,否则将其转换为原始类型
另外:
+
号两边只要有一个是字符串,都会把另外一个转成字符串- 除了
+
以外的算术运算符 比如- * /
等都会把数据转成数字类型 - 逻辑非
!
转换为布尔 +
号作为正号解析可以转换成数字型- 任何数据和字符串相加结果都是字符串
JavaScrip类型转换详解
转换成Number类型
转为Number类型:++ / --
(自增自减运算符) + - * / %
(算术运算符) > < >= <= == != === !==
(关系运算符)。null
转换为数字为0
, undefined
为NaN
简单数据转换数字对照:
原始数据类型 | 转换之后的值 |
---|---|
空字符 ''或"" | 0 |
非空字符串 | 将字符内的数据内容变为数据,如果还有其他符号中文等转为NaN |
true | 1 |
false | 0 |
null | 0 |
undefined | NaN |
NaN | (不用转,typeof NaN 得到"number") |
示例:
// 隐式转换为数字型的运算符 // 算术运算符 - * / 比较运算符 > == console.log(8 - '3') // 5 console.log('1999' * '2') // 3998,此处两个string型全都得转换为number型 console.log('35' - 34) //1 console.log('35' - '34') //1 console.log('40' / '2') //20 console.log('35' % 2) //1 console.log('35' % '2') //1 console.log(5 - undefined) //NaN 因为Undefined转为数字为NaN console.log(5 - null) //5 console.log(44%('2a')) //NaN,其中,2a进行强转后为NaN,NaN参与运算返回NaN console.log('5'>'3') //true 此处直接比较的ASCII码。 console.log(3 > '1') // true console.log(3 == '3') // true console.log(3 == '+3') // true,此处的+号相当于是类型转换 console.log(3 == '-3') // false console.log(3 == '*3') // false console.log(3 == '/3') // false console.log(3 == 'a3') // false console.log('a' == 97) // false console.log('a' > 'A') // true 此处比较的是ASCII码,其中a为97 A为65,因此为true console.log('a' > '') // true console.log('' == 0) //true // + 正号使用的时候,也会把字符串转换为 数字型 console.log('123') // '123' console.log(+'123') // 123 console.log(typeof +'123') // number console.log(+'0x12' == 18) // true console.log('55' + true) //'55true' // undefined、null、boolean类型转换为数字 console.log(NaN == NaN) //false,NaN比较特殊,它自己不等于自己 console.log(undefined == 0) //false console.log(undefined == NaN) //false console.log(undefined == null) //true,此处undefined和null值都为空,因此能够相等 console.log(null == 0) //false 此处没有进行类型转换,因为null是一个值类型,它的数值就是null,我们在使用==时,会直接把null这个数值与0进行比较,结果为false console.log(null === 0) // false console.log(null >= 0) //false null要进行数值比较,此处便会尝试转为number,则为0,结果为 true console.log(false == null) //false 特殊情况,理论上都应该转换为0比较然后相等true,但实际是直接拿值比较,不会先转为为数字 console.log(true == 1) //true console.log(false == 1) //false console.log(true > false) //true 先转化为1和0数字进行比较 console.log(true + 1) // 2 console.log(true + null) //1,其中true转换为1,null转换为0 console.log(undefined + 1) // NaN console.log('5' - true) //4 console.log('5' - false) //0 //数组转换为数字 console.log([9] == 9) //true console.log([9,'a'] == 9) //false //特殊情况 console.log({} == {}) // false,对象类型比的是地址,不同对象地址不同 console.log([]==[]) // false,理由同上
转换为String类型
简单数据转换字符串对照:
原始数据类型 | 转换之后的值 |
---|---|
数字类型 | 数字类型的字符表示 |
null | ‘null’ |
undefined | ‘undefined’ |
布尔类型 | true变’true’,false变’false’ |
此处注意点为-0
转换为string类型为'0'
["a","b"]
转换string类型为"a,b"
[]
转换为string类型为""
转换为Boolean类型
数据逻辑判断和逻辑运算之中会隐式转换为boolean类型
转换为布尔型:空字符、0、-0、undefined、null、false、NaN
转换为布尔值后为false,其余为true
+
号两边只要有一个是字符串,都会把另外一个转成字符串
连续使用两个非操作符(!!)可以将一个数强制转换为boolean类型,这在开发之中比较实用。
简单数据转换布尔型对照:
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
String | 任何非空字符串 | 空字符串(""或’') |
Number | 任何非零数字 | 0和NaN |
Object | 任何对象 | null |
Undefined | 不适用 | undefined |
示例:
//隐式转换为布尔型的运算符 !逻辑非 console.log(!true) // false console.log(!0) // true console.log(!'') // true console.log(!null) // true console.log(!undefined) // true console.log(!NaN) // true console.log(!false) // true console.log(!'hello') // false
JavaScrip特殊操作符对类型转换的影响
!逻辑非运算符
!
会将后面的数据先转成布尔值,然后取反
var a; //a = undefined var r = !!a; console.log(r) //false !!{} // true !!undefined // false !!null // false !!NaN //fales
== 相等运算符
比较操作符会为两个不同类型的操作数转换类型,然后进行严格比较。当两个操作数都是对象时,JavaScript会比较其内部引用,当且仅当他们的引用指向内存中的相同对象时才相等,即他们在栈内存中的引用地址相同。
1.类型相同
如果比较的是两个对象,则比较两个对象的指针是否指向同一个对象
let a = {} let b = {} a==b //false let a = {} let b = a; a==b //true
2.类型不同
如果两边类型不同,则两边都尝试转成number类型。对于引用类型,先调用valueOf()
,如果能转成数字,则进行比较。不能转成数字就调用toString()
方法转成字符串。
tips:因为
null
是一个值类型,它的数值就是null
,我们在使用==时,会直接把null
这个数值与数值进行比较,而不是转换为0
console.log(3 == '3') // true console.log(3 == '+3') // true,此处的+号相当于是类型转换 console.log(3 == '-3') // false console.log(3 == 'a3') // false console.log(+'0x12' == 18) // true console.log('' == 0) //true console.log(null == 0) //false 此处没有进行类型转换,因为null是一个值类型,它的数值就是null,我们在使用==时,会直接把null这个数值与0进行比较,结果为false console.log(NaN == NaN) //false,NaN比较特殊,它自己不等于自己 console.log(undefined == 0) //false console.log(undefined == NaN) //false console.log(undefined == null) //true,此处undefined和null值都为空,因此能够相等
面试题
//问题1: console.log(new String('abc') == true)//flase //step1:右侧转成数字1,变成: new String('abc')==1 //step2 new String('abc').valueOf()不是数字也不是字符串,再调用toString() 'abc' == 1 //step3:字符串转数字 NaN == 1 //false,NaN和任何类型比较都为false //问题2: console.log({}==true)//false //step1:右侧转成数字 {} == 1 //step2 {}.valueOf()不是数字也不是字符串,再调用toString() '[object Object]' ==1 //step3:字符串转数字 NaN == 1 //false,NaN和任何类型比较都为false //问题3: console.log([]==![])//true //step1:!优先级比==高,先转右边,[]是对象类型,转成布尔值为true,!true就是false []==false //step2:右侧转成数字为0 []==0 //step3:左侧是一个对象,valueOf()转出来不是字符也不是字符串,调用toString(),得到空字符串 '' == 0 //step4:字符串转成数字 0 == 0 //true
比较运算符
字符串类型比较大小时,不进行类型转换,而是逐位比较ASCII码,第一位不同则返回结果,否则继续比较第二位,直到某一位不同为止。
字符串与数字或者boolean与数字比较时,会进行隐式数据类型转换
示例
console.log('5555555' < '6') //true,首先比较第一个字符串的第一个字符,如果不同直接返回结果 console.log('5'>'3') //true,此处直接比较的ASCII码。 console.log(3 > '1') // true console.log('a' > 'A') // true,此处比较的是ASCII码,其中a为97 A为65,因此为true console.log('a' > '') // true console.log(null >= 0) //false,null要进行数值比较,此处便会尝试转为number,则为0,结果为 true
+ 算数运算符
当+
号作为一元操作符时,它就会将这个数转换为数字类型
当+
号作为二元操作符时
console.log(3 == '+3') // true,此处的+号相当于是类型转换 console.log('55' + true) //'55true' console.log(true + 1) // 2 console.log(true + null) //1,其中true转换为1,null转换为0 console.log(undefined + 1) // NaN
+
号两边只要有一个是字符串,都会把另外一个转成字符串,此时+
号为连接符