美文网首页
把其他数据类型转型为Number

把其他数据类型转型为Number

作者: 小生菜呢 | 来源:发表于2021-07-22 14:47 被阅读0次

js中的数据类型:

1.原始值类型:
  • number
  • string
  • boolean
  • symbol
  • undefiend
  • null
  • bigint
2.对象类型:
  • 标准普通对象
  • 标准特殊对象
  • 非标准特殊对象
  • 可调用对象(函数对象)

【JS中的数据类型和检测:】https://www.jianshu.com/p/1c83b872154f

其他类型转为Number:

一般来说有两大方案:

一、Number([val])

  • 一般情况下我们不会手动来用Numer来转(但是写了也没问题)

这种方式一般都是通过隐式转换来完成的

什么是隐式转换?就是浏览器自己通过Nunber()来转换

什么情况下会存在隐式转换呢?常用的有以下三种:
@1. 数学运算

10-'5' = 5  // => Number('5')
10 + '5' = '15' // 字符串拼接

@2. isNaN检测

isNaN(true)  // false           => isNaN(Number(true))
isNaN('12px' ) // true          => isNaN(Number('12px')) (Number([val]) val有过有一个无效字符,结果就是NaN)

@3. ==比较
两边类型不一样,要默认转换成一样的类型进行比较
.......

  • 其他类型转换为Number的一些规则:
    @1. 字符串转为数字:空字符串变为0,如果出现任何非有效数字都是NaN
    image.png
    @2. 把布尔烈性转为数字:true -> 1,false -> 0
    @3. null -> 0 undefined -> NaN
    image.png
    @4. Symbol无法转换为数字,会报错:
image.png
@5.bigInt去除'n'(超过安全数字的,会按照科学计数法处理)
image.png
所以一般情况下bigInt还是转为字符串比较合适

@6.把对象转换为数字:

  • 先调用对象的Symbol.toPromitive 这个方法,如果不存在这个方法
  • 再调用对象的 valueof 获取原始值,如果获取的值不是原始值
  • 再调用对象的 toString 把其变为字符串
  • 最后再把字符串基于 Number方法转换为数字

举个例子:

let obj = {
  name: 'zhangsan'
}
console.log(Number(obj)) // -> NaN

执行步骤:
obj[Symbol.toPromitive] :没有Symbol.toPromitive,执行valueOf()
obj.ValueOf() :执行valueOf()得到的不是原始值,是对象:{name: "zhangsan"},再去执行toString()
obj.toString() -> "[object Object]"
Number("[object Object]") -> NaN

image.png
let arr1 = [10],
     arr2=[10,20]
console.log(Number(arr1 )) //  -> 10
console.log(Number(arr2 )) // -> NaN
image.png
image.png

普通标准对象{}和标准特殊对象[]都没有toPrimitive属性,下面来看一个有toPrimitive属性的

let time = new Date()
console.log(Number(time))
image.png
  • 经验证time[Symbol.toPrimitive]的值是个函数,说明日期对象有这属性
  • 接下来把这个属性执行 ,直接执行会报错,如下图
image.png
  • 所以这个属性执行的时候要传值(hint),传递的值有3种:'number','string','default',传的值不同,结果也不同
    image.png

浏览器会帮我们判断,如果是转成数字,会传'number',如果是转成字符串,会传'string',如果浏览器也不确定,传'default'


image.png

上图中,浏览器帮我们处理1时,实际过程就是2,处理3时,实际过程就是4

接下来再通过一个例子来验证下这个规则:
给obj写个[Symbol.toPromitive]属性,执行代码看下结果

let obj = {
  name:'张三',
  [Symbol.toPrimitive](hint) {
    console.log(hint)
    return 10
  }
}
console.log(Number(obj)) // 'number'  Number(10)  -> 10
console.log(String(obj)) //'string'  String('10') -> '10' 
console.log(obj.toString()) // '[object Object]'

确认验证结果:
1.如果有[Symbol.toPrimitive]这个属性,是溪岸执行这个属性
2.执行[Symbol.toPrimitive]时,浏览器会默自己判断hint传的值是什么值
3.注意:直接调用obj的toString()时,走的是Object.prototype.toString().call(obj)这套逻辑,这不是把它转换为字符串,所以不走Symbol.toPromitive
4.对象不管是转数字还是转字符串,都是按:[Symbol.toPromitive],valueOf(),toString(),数字的话再加个Number()这顺序来转换的

再来看个例子

let arr = [10]
arr[Symbol.toPrimitive] = function(hint) {
  console.log(hint)
  return 0
}
console.log(arr.toString()) //'10'    直接调用原型的方法,不会走 Symbol.toPrimitive这个逻辑
console.log(arr + '') // 'default'  '0'
  • 第一个console.log()中,arr也是直接调的toString(),同上个例子一样,也只直接调的类的原向上的方法,所以结果是'10'
  • 第二个console得到的结果是‘default’ 和字符串'0',是因为:数组+字符串,需要把arr隐士转换为字符串[需要走Symbol.toPromitive这套逻辑,hint为‘default’],然后再进行字符串拼接
    为什么hint是'default'不是'string'呢?因为+号既是数学运算,也是字符串拼接,浏览器此时不确定是哪种情况,所以hint是default,

所以,把一开始的规则补充冲总结下就是:
当我们把对象隐士转换为数字或者字符串的时候[使用的方法:Nymber()/String()],会有一套自己的处理逻辑:
@1、检测Symbol.toPrimitive,如果有这个方法,浏览器会把方法执行,传递hint[根据场景不一样,浏览器默认传递的值也不同:'number','string','default' ];如果没有这个方法,则进行下一步;
@2、基于valueOf获取原始值,如果获取的不是原始值,再进行下一步;
@3、基于toString获取字符串
@4、如果需要转的是数字,则再次把字符串转为数字即可
注意:如果是直接对象.toString(),详单与直接调用第三个步骤[直接调用所属类原型上的toString方法],此时直接获取字符串,不会走这四步的逻辑

二、parseInt([val],[radix])和parseFloat([val])

  • 这种情况就不是隐式转换了,也就是我们说的手动转换,这两个的处理规则就和Number完全不一样了
  • 规则:[val]必须是一个字符串,如果不是则先转为字符串:然后从第一个字符开始查找,把找到的有效数字转为数字,一个都没找到就是NaN;遇到一个非有效字符,不论后边是否是有效数字,都不用再查找了;parseFloat比parseInt多识别一个小数点

测试题

console.log(parseInt('10'))
console.log(Number('10'))

console.log(parseInt('10px'))
console.log(Number('10px'))

console.log(parseInt(null))
console.log(Number(null))
  • 第一组:10 10
  • 第二组:10 NaN
    console.log(parseInt('10px'))遇到p停止查找,所以是10
    console.log(Number('10px'))有一个非有效字符就是NaN
  • 第三组 NaN 0
    console.log(parseInt(null)):先把null转为字符串,结果是空字符串"",parseInt从左都右,一个有效字符否没找到,所以是NaN

.

相关文章

网友评论

      本文标题:把其他数据类型转型为Number

      本文链接:https://www.haomeiwen.com/subject/qxismltx.html