把其他数据类型转型为Number

2021-07-22  本文已影响0人  小生菜呢

js中的数据类型:

1.原始值类型:
2.对象类型:

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

其他类型转为Number:

一般来说有两大方案:

一、Number([val])

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

什么是隐式转换?就是浏览器自己通过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. ==比较
两边类型不一样,要默认转换成一样的类型进行比较
.......

image.png
@5.bigInt去除'n'(超过安全数字的,会按照科学计数法处理)
image.png
所以一般情况下bigInt还是转为字符串比较合适

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

举个例子:

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 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'

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

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

测试题

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

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

console.log(parseInt(null))
console.log(Number(null))

.

上一篇下一篇

猜你喜欢

热点阅读