JavaScript 类型转换

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

原始数据类型如何具有属性操作的? ***

  • 前置知识: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 作者:梳梳

(0)
上一篇 2023年5月23日 上午10:05
下一篇 2023年5月23日 上午10:15

相关推荐

发表回复

登录后才能评论