isNaN 和 Number.isNaN 的区别? **
-
isNaN 包含了一个隐式转化
- isNaN => 接收参数 => 尝试参数转成数值型 => 不能被转数值的参数 返回 true => 非数字值传入返回 true
-
Number.isNaN => 接收参数 => 判断参数是否为数字 => 判断是否为 NaN => 不会进行数据类型转换
既然说到了类型转换,有没有其他的类型转换场景? ***
转换成字符串
-
Null 和 Undefined => ‘null’ ‘undefined’
-
Boolean => ‘true’ ‘false’
-
Number => ‘数字’ 大数据 会转换成带有指数形式
-
Symbol => ‘内容’(隐式转换会发生错误)
-
普通对象 => ‘[Object Object]’
转成数字
-
undefined => NaN
-
Null => 0
-
Boolean => true | 1 false | 0
-
String => 包含非数字的值 NaN 空 0
-
Symbol => 报错
-
对象 => 相应的基本值类型 => 相应的转换
转成 Boolean
-
undefined | null | false | +0 -0 | NaN | “” => false
原始数据类型如何具有属性操作的? ***
-
前置知识:js 的包装类型
-
原始数据类型,在调用属性和方法时,js 会在后台隐式地将基本类型转换成对象
let a = 'zhaowa'
a.length // 6
// js在收集阶段
Object(a) // String { 'zhaowa' }
// => 去包装
let a = 'zhaowa'
let b = Object(a)
let c = b.valueOf() // 'zhaowa'
- 说说下面代码执行结果?
let a = new Boolean(false) // => Boolean {},a 被赋值之后,经过包装现在就是一个对象
if (!a) {
console.log('hi zhaowa')
}
// never print
把其他数据类型转换为Number
Number([val])
-
浏览器的隐式转换
-
数学运算
-
isNaN检测
-
==比较
-
-
规则
-
字符串转换为数字
-
空字符串变为 0
-
如果出现任何非有效数字字符,结果都是NaN
-
-
把布尔转换为数字
- true->1 false->0
-
null->0 undefined->NaN
-
Symbol无法转换为数字,会报错
- Uncaught TypeError: Cannot convert a Symbol value to a number
-
BigInt去除“n”
- 超过安全数值的,会按照科学计数法处理
-
把对象转换为数字
-
调用对象的 Symbol.toPrimitive 这个方法,如果不存在这个方法
-
再调用对象的 valueOf 获取原始值,如果获取的值不是原始值
-
再调用对象的 toString 把其变为字符串
-
最后再把字符串基于Number方法转换为数字
-
-
let time = new Date()
console.log(Number(time))
/*
首先检测 Symbol.toPrimitive 有没有,结果:有,而且是个函数
time[Symbol.toPrimitive]('number')
*/
let arr = [10]
console.log(Number(arr))
/*
首先 arr[Symbol.toPrimitive] -> undefined
其次 arr.valueOf() 获取原始值 -> [10] 不是原始值
再此 arr.toString() 转换为字符串 -> '10'
最后 再把字符串‘10’转化为数字 -> 10
*/
let num = new Number(10)
console.log(Number(num))
/*
首先 num[Symbol.toPrimitive] -> undefined
其次 num.valueOf() -> 10
*/
parseInt([val],[radix]) parseFloat([val])
-
[val]不是字符串 => 隐式转换为字符串 String([val])
-
从字符串左侧第一个字符开始找,把找到的有效数字字符最后转换为数字
- 一个都没找到就是NaN
-
遇到一个非有效数字字符 => 停止查找
-
parseFloat可以多识别一个小数点
-
[radix]进制
-
不写 / 写零:默认是10
- 字符串是以0x开始的,默认值是16
-
有效范围:2~36之间
- 不在这个区间,结果直接是NaN
-
-
从[val]字符串左侧第一个字符开始查找,查找出符合[radix]进制的值,把找到的内容,按照[radix]进制,转换为10进制
- 遇到不符合的则结束查找,不论后面是否还有符合
console.log(parseInt('10102px13', 2)) //10
// 找到符合二进制的 '1010'
// 把这个二进制的值转换为10进制 “按权展开求和”
// 1*2^3+0*2^2+1*2^1+0*2^0 => 8+0+2+0 => 10
let arr = [27.2, 0, '0013', '14px', 123]
arr = arr.map(parseInt)
console.log(arr) //[27, NaN, 1, 1, 27]
parseInt(27.2, 0)
// parseInt('27.2',10)
// '27' 把其当做10进制转换为10进制 => 27
parseInt(0, 1)
// NaN
parseInt('0013', 2)
// '001' 当做2进制转换为10进制
// 0*2^2+0*2^1+1*2^0 -> 0+0+1 => 1
parseInt('14px', 3)
// '1' 当做3进制转换为10进制
// 1*3^0 -> 1
parseInt(123, 4)
// parseInt('123',4)
// '123' 当做4进制转换为10进制
// 1*4^2+2*4^1+3*4^0 -> 16+8+3 => 27
// JS中遇到以0开始“数字”,会默认把其按照8进制转为10进制,然后在进行其他操作
parseInt(0013, 2)
// 先8转10 0*8^3+0*8^2+1*8^1+3*8^0 -> 0+0+8+3 => 11
parseInt('11', 2)
// '11'
// 在2转10 1*2^1+1*2^0 -> 2 + 1 -> 3
把其他数据类型转换为String
拿字符串包起来
- 特殊:Object.prototype.toString
String([val]) 或者 [val].toString()
“+”除数学运算,还可能代表的字符串拼接
-
出现左右“两边”,其中一边是字符串,或者是某些对象:会以字符串拼接的规则处理
-
出现在一个值的左边,转换为数字
let num = '10'
console.log(+num) //10
let i = '10'
i++ //一定是数学运算
console.log(i) //11
i = '10'
i += 1
console.log(i) //'101'
i = '10'
i = i + 1
console.log(i) //'101'
let result = 100 + true + 21.2 + null + undefined + 'Tencent' + [] + null + 9 + false
NaN + 'Tencent'
// "NaNTencent"
arr[Symbol.toPrimitive]
// undefined
arr.valueOf()
// 获取原始值 -> [] 不是原始值
// arr.toString() 转换为字符串 -> ''都是字符串拼接
console.log(result) //"NaNTencentnull9false"
console.log(10 + '10') //"1010"
console.log(10 + new Number(10)) //20
// new Number(10)[Symbol.toPrimitive] -> undefined
// new Number(10).valueOf() -> 10
// 10+10 => 20
console.log(10 + new Date()) //'10Wed Apr 06 2022 22:01:38 GMT+0800 (中国标准时间)'
// new Date()[Symbol.toPrimitive]('default') -> 'Wed Apr 06 2022 22:01:38 GMT+0800 (中国标准时间)'
console.log(10 + [10]) //'1010'
[10].toString()
// '10' => 10+'10'
把其他数据类型转换为Boolean
除了“0 / NaN / 空字符串 / null / undefined”五个值是 false,其余都是true
Boolean([val]) 或者 !/ !!
条件判断
const fn = (num) => {
if (num == null) {
// num是null或者undefined
}
}
// console.log(NaN == NaN)//false
// console.log(Object.is(NaN, NaN)) //true
“==”比较时候的相互转换规则
“==”相等,两边数据类型不同 => 先转为相同类型,再进行比较
-
对象==字符串
-
对象转字符串
-
Symbol.toPrimitive -> valueOf -> toString
-
-
null==undefined -> true
- null/undefined和其他任何值都不相等
-
null===undefined -> false
-
对象==对象
- 比较的是堆内存地址,地址相同则相等
-
NaN!==NaN // true
-
除了以上情况,只要两边类型不一致,剩下的都是转换为数字再进行比较的
“===”绝对相等,两边类型不同,则直接是false,不会转换数据类型「推荐」
console.log([] == false) //都转换为数字 0==0 => true
console.log(![] == false) //先处理 ![]=>false false==false => true
原文链接:https://juejin.cn/post/7235965352201961528 作者:梳梳