# 6、数据类型与隐式转换
# 1.数据类型分类
(1)基本数据类型【7】
string、 number、null、undefined、 boolean、bigInt、symbol
注意⚠️:
Number类型中NaN不是有效数字但是属于Number类型,typeof NaN //=> 'number'
NaN === NaN // => false
Object.is(NaN,NaN) // => true
BigInt出现的意思是保证超出最大最小安全值仍然可以准确计算
console.log(Number.MAX_SAFE_INTEGER); //=>9007199254740991
console.log(Number.MIN_SAFE_INTEGER); //=>-9007199254740991
9007199254740991n =>bigint类型的
(2)引用数据类型【2】
- object - 普通对象 {} Map - 实例对象 new xxx - 日期对象 new Date - 正则对象 new RegExp - 原型对象 prototype - 数组对象 Set Array - 。。。
- function
# 2.数据类型的检测
- typeof 能检测基本类型和函数类型,但是对于对象类型和null不能区分(null为计算机历史遗留问题) typeof function(){} // 'function' typeof NaN // 'number'
- constructor [].constructor === Array
- instanceof
- Object.prototype.toString.call() Object.prototype.toString.call([]) // "[object Array]"
# 3.数据类型的隐式转换
(1)转化为Number类型的情况
使用Number显式类型转换, 转换过程中,遇到对象会先toString然后在Number转换
例子: Number()、Number(null)、Number("")、Number(false) 结果为 0 Number(undefined) 、 Number({})、 Number('wds'), 结果为 NaN Number(true) , 转化结果为 1 Number(['2222']) 结果为 2222 Number(['2222','1111']) 结果为NaN Number('1,2')
使用加号减号等运算符隐式转换, 转换过程中,遇到对象会先toString然后在Number转换
例子: + '123' 结果为 123 + [] 、+null、+false 结果为 0 + {}、+ 'abc' 、+ undefined 结果为 NaN + true 结果为 1 1 + true 结果为 2 注意⚠️: NaN + 任何数都是NaN、字符串和对象除外,会转成字符串拼接 NaN+123、NaN+ true、NaN+NaN 结果都为NaN NaN + {} 结果为 "NaN[object Object]" NaN + [] 结果为 "NaN"
使用isNaN进行检测的时候,会隐式转换为数字在检测,,转换过程中,遇到对象会先toString然后在Number转换
验证是不是无效数字,无效返回true 例子: isNaN(123) 、 isNaN('') 、isNaN('2222') 、 isNaN(false)、isNaN(true) 、isNaN(null) 、 isNaN([]) 结果为 false 结果为true 结果为false isNaN(undefined)、、 isNaN(NaN) 、
使用parseInt、parseFloat转换
先转成字符串,然后从左到右检测有效数字,如果没有检测到有效数字结果就为 NaN 例子: parseInt('112abc') 结果为 112 parseInt('abc')、parseInt('abc22222') 结果为 NaN parseFloat('2.22'+'aa') 结果为 2.22 parseFloat('2e'+'3') 结果为 2000 科学计数法例外
在==比较的时候,有些值需要转换为数字再进行比较
一道parseInt面试题
let arr = [10.18,0,14,35,23] arr = arr.map(parseInt) console.log(arr) // 解体思路 // 可以转化为arr.map((el,idx)=>parseInt(el,idx)) //返回一个数组 // 元素分别求 // parseInt(10.18,0) => 10 // parseInt(0,1) => NaN parseInt的进制范围是2~36, 1 不在该范围返回NaN // parseInt(14,2) => 从左向右检测进制2,数字范围0~1,所以4没有,相当于1的2进制转化为10进制,1*2^0 = 1, 结果为1 // parseInt(35,3) => 因为3进制数字范围0~2, 3和5都不在这个范围,返回NaN // parseInt(23,4) => 2*4^1+3*4^0 = 11 // 结果为[10,NaN,1,NaN,11]
(2)转化为String类型的情况
使用String或者toString显式类型转换
例子: String(123) 结果为"123" String(true) 结果为"true" String(undefined) 结果为"undefined" String([]) 结果为"" String({}) 结果为"[object Object]" * 会调用原型上的toString()方法 注意⚠️: 123.toString() 会报错,因为会解析成(123.)toString(), 正确写法 (123).toString() 或者 123..toString 或者123 .toString
使用➕号连接的时候,如果一边有字符串或者有对象(会先调用toString()解析为字符串),那么会进行字符串的拼接
例子: 1 + 'hello' 结果为 "1hello" 1 + [] 结果为 "1" 1 + {} 结果为"1[object Object]" NaN + {} 结果为 "NaN[object Object]"
(3)转化为Boolean
Boolean 强制转化
例子: Boolean(null)、Boolean(0) 、Boolean(“”)、Boolean(NaN)、Boolean(undefined) 结果为false 除上面五个,其他值转换都为true Boolean('haha') 、Boolean([]) 、 Boolean({}) 、Boolean(1) 结果为true
!、!! 隐式转换
! 结果为Boolean的相反 !! 结果为Boolean的值 例子: ! null 、!"" 、 !undefined 、!NaN、!0 结果为true !! undefined 结果为false
(4)“==”的隐式转化
- 两个 == 比较值,三个===号值和类型都比较
如果遇到对象会转换为字符串在比较 例子 [] == [] 输出 false 对象比较对内存地址 null == undefined 输出true '123' == 123、'123' == [123] 、 '123' == ['123'] 输出都是true
# 练习题
parseInt(""); // 输出NaN
parseInt(null); // 输出NaN
parseInt("12px") // 输出12
parseFloat("1.6px") + parseInt("1.2px") + typeof parseInt(null) // 输出'2.6NaN' 1.6 + 1 + typeof NaN
Number("") // 输出0
Number(null) // 输出0
Number("12px") // 输出NaN
Number(!!Number(parseInt("0.8"))) // 输出0 0.8 => 0 => 0 => false => 0
isNaN("") // 输出false "" => 0 =>false
isNaN(null) // 输出false null => 0 => false
isNaN("12px") // 输出true
isNaN(Number(!!Number(parseInt("0.8")))) // 输出false isNaN(0)
typeof !parseInt(null) + !isNaN(null)
let a = typeof typeof typeof [12,23]; // 'string'
// 输出'booleantrue'
// typeof !(NaN) + !(isNaN(Number(null)))
// typeof true + !(isNaN(0)) => 'boolean'+ true => 'booleantrue'
let result = 12+false+undefined+[]+'Test'+null+true+{};
console.log(result);
// 12 + false => 12 + 0 => 12
// 12 + undefined => 12 + NaN => NaN
// NaN + [] => NaN + Number([]) => NaN + Number([].toString()) => NaN + Number('') => NaN
// NaN+'Test' => 'NaNTest'
// 'NaNTest'+null => 'NaNTestnull'
// 'NaNTestnull'+true => 'NaNTestnulltrue'
// 'NaNTestnulltrue'+ {} => 'NaNTestnulltrue'+ {}.toString() => 'NaNTestnulltrue[object Object]'
# JS进阶(一)数据类型与隐式转换
## 1.数据类型分类
(1)基本数据类型【7】
> **string、 number、null、undefined、 boolean、bigInt、symbol**
注意⚠️:
```js
Number类型中NaN不是有效数字但是属于Number类型,typeof NaN //=> 'number'
NaN === NaN // => false
Object.is(NaN,NaN) // => true
BigInt出现的意思是保证超出最大最小安全值仍然可以准确计算
console.log(Number.MAX_SAFE_INTEGER); //=>9007199254740991
console.log(Number.MIN_SAFE_INTEGER); //=>-9007199254740991
9007199254740991n =>bigint类型的
```
(2)引用数据类型【2】
>- **object**
> - 普通对象 {} Map
> - 实例对象 new xxx
> - 日期对象 new Date
> - 正则对象 new RegExp
> - 原型对象 prototype
> - 数组对象 Set Array
> - 。。。
>- **function**
## 2.数据类型的检测
> - **typeof**
> 能检测基本类型和函数类型,但是对于对象类型和null不能区分(null为计算机历史遗留问题)
> typeof function(){} // 'function'
> typeof NaN // 'number'
> - **constructor**
> [].constructor === Array
> - **instanceof**
> - **Object.prototype.toString.call()**
> Object.prototype.toString.call([]) // "[object Array]"
## 3.数据类型的隐式转换
**(1)转化为Number类型的情况**
- 使用Number显式类型转换, 转换过程中,遇到对象会先toString然后在Number转换
>**例子:**
>Number()、Number(null)、Number("")、Number(false) 结果为 0
>Number(undefined) 、 Number({})、 Number('wds'), 结果为 NaN
>Number(true) , 转化结果为 1
>Number(['2222']) 结果为 2222
>Number(['2222','1111']) 结果为NaN
>Number('1,2')
- 使用加号减号等运算符隐式转换, 转换过程中,遇到对象会先toString然后在Number转换
>**例子:**
>
>+ '123' 结果为 123
> + [] 、+null、+false 结果为 0
> + {}、+ 'abc' 、+ undefined 结果为 NaN
> + true 结果为 1
> 1 + true 结果为 2
> 注意⚠️: NaN + 任何数都是NaN、字符串和对象除外,会转成字符串拼接
> NaN+123、NaN+ true、NaN+NaN 结果都为NaN
> NaN + {} 结果为 "NaN[object Object]"
> NaN + [] 结果为 "NaN"
- 使用isNaN进行检测的时候,会隐式转换为数字在检测,,转换过程中,遇到对象会先toString然后在Number转换
> **验证是不是无效数字,无效返回true**
> **例子:**
> isNaN(123) 、 isNaN('') 、isNaN('2222') 、 isNaN(false)、isNaN(true) 、isNaN(null) 、 isNaN([])
> 结果为 false
> 结果为true
> 结果为false
> isNaN(undefined)、、 isNaN(NaN) 、
- 使用parseInt、parseFloat转换
> **先转成字符串,然后从左到右检测有效数字,如果没有检测到有效数字结果就为 NaN**
> **例子**:
> parseInt('112abc') 结果为 112
> parseInt('abc')、parseInt('abc22222') 结果为 NaN
> parseFloat('2.22'+'aa') 结果为 2.22
> parseFloat('2e'+'3') 结果为 2000 科学计数法例外
- 在==比较的时候,有些值需要转换为数字再进行比较
*一道parseInt面试题*
```js
let arr = [10.18,0,14,35,23]
arr = arr.map(parseInt)
console.log(arr)
// 解体思路
// 可以转化为arr.map((el,idx)=>parseInt(el,idx))
//返回一个数组
// 元素分别求
// parseInt(10.18,0) => 10
// parseInt(0,1) => NaN parseInt的进制范围是2~36, 1 不在该范围返回NaN
// parseInt(14,2) => 从左向右检测进制2,数字范围0~1,所以4没有,相当于1的2进制转化为10进制,1*2^0 = 1, 结果为1
// parseInt(35,3) => 因为3进制数字范围0~2, 3和5都不在这个范围,返回NaN
// parseInt(23,4) => 2*4^1+3*4^0 = 11
// 结果为[10,NaN,1,NaN,11]
(2)转化为String类型的情况
使用String或者toString显式类型转换
例子: String(123) 结果为"123" String(true) 结果为"true" String(undefined) 结果为"undefined" String([]) 结果为"" String({}) 结果为"[object Object]" * 会调用原型上的toString()方法 注意⚠️: 123.toString() 会报错,因为会解析成(123.)toString(), 正确写法 (123).toString() 或者 123..toString 或者123 .toString
使用➕号连接的时候,如果一边有字符串或者有对象(会先调用toString()解析为字符串),那么会进行字符串的拼接
例子: 1 + 'hello' 结果为 "1hello" 1 + [] 结果为 "1" 1 + {} 结果为"1[object Object]" NaN + {} 结果为 "NaN[object Object]"
(3)转化为Boolean
Boolean 强制转化
例子: Boolean(null)、Boolean(0) 、Boolean(“”)、Boolean(NaN)、Boolean(undefined) 结果为false 除上面五个,其他值转换都为true Boolean('haha') 、Boolean([]) 、 Boolean({}) 、Boolean(1) 结果为true
!、!! 隐式转换
! 结果为Boolean的相反 !! 结果为Boolean的值 例子: ! null 、!"" 、 !undefined 、!NaN、!0 结果为true !! undefined 结果为false
(4)“==”的隐式转化
两个 == 比较值,三个===号值和类型都比较
如果遇到对象会转换为字符串在比较 例子 [] == [] 输出 false 对象比较对内存地址 null == undefined 输出true '123' == 123、'123' == [123] 、 '123' == ['123'] 输出都是true
# 练习题
js parseInt(""); // 输出NaN parseInt(null); // 输出NaN parseInt("12px") // 输出12 parseFloat("1.6px") + parseInt("1.2px") + typeof parseInt(null) // 输出'2.6NaN' 1.6 + 1 + typeof NaN Number("") // 输出0 Number(null) // 输出0 Number("12px") // 输出NaN Number(!!Number(parseInt("0.8"))) // 输出0 0.8 => 0 => 0 => false => 0 isNaN("") // 输出false "" => 0 =>false isNaN(null) // 输出false null => 0 => false isNaN("12px") // 输出true isNaN(Number(!!Number(parseInt("0.8")))) // 输出false isNaN(0) typeof !parseInt(null) + !isNaN(null) let a = typeof typeof typeof [12,23]; // 'string' // 输出'booleantrue' // typeof !(NaN) + !(isNaN(Number(null))) // typeof true + !(isNaN(0)) => 'boolean'+ true => 'booleantrue'
```js let result = 12+false+undefined+[]+'Test'+null+true+{}; console.log(result);
// 12 + false => 12 + 0 => 12 // 12 + undefined => 12 + NaN => NaN // NaN + [] => NaN + Number([]) => NaN + Number([].toString()) => NaN + Number('') => NaN // NaN+'Test' => 'NaNTest' // 'NaNTest'+null => 'NaNTestnull' // 'NaNTestnull'+true => 'NaNTestnulltrue' // 'NaNTestnulltrue'+ {} => 'NaNTestnulltrue'+ {}.toString() => 'NaNTestnulltrue[object Object]' ```
js let res = parseFloat('left:200px') //=> NaN if(res===200){ alert(200) }else if(res === NaN){ // => NaN === NaN false alert(NaN) }else if(typeof res === 'number'){ alert('number') //=> 'number' alert 输出结果都会转化为字符串 }else{ alert('Invalid Number') }
# 知识延伸
# 写在最后
欢迎访问我的博客rockshang.com
## 知识延伸
[习题](https://juejin.im/post/5ee03947e51d457889262921?utm_source=gold_browser_extension#heading-40)
## 写在最后
欢迎访问我的博客[rockshang.com](https://s2265681.github.io/)