为什么要写这篇文章
最近在阅读《javascript高级程序设计》(第6版)这本书,以写代记。同时刚刚入职新公司,发现自己对于number类型转换的细节掌握不足
使用场景
我们常常对于很多字符串类型的数字需要转换成Number
,一般使用Number()
,就可以实现,但是Number()
有一些弊端,比如使用Number()
一旦含有非数字类型就会返回NaN
,比如Number(’123b’)—>NaN
,其实很有可能我们的目的是筛选出字符串中的数值,然而他却返回了NaN
,导致条件无法满足,程序无法执行。所以根据不同的场景和目的,会使用不同的数值转换函数:
Number(string)
:适用于只包含数字的转换parseInt(string, radix)
:适用于整数,进制数值转换,含num+非num的转换parseFloat(string)
:适用于浮点数的转换
注意: 这里的parseInt(
)和parseFloat()
,与Number.parseInt()
,Number.parseFloat()
相同
思维导图
个人习惯,每次记录一些东西喜欢先用思维导图,一个是简单直观,还有一个是缕清思路,见者不喜勿怪哈
Number(string)
区别于New Number()
new Number()
表示Number实例,Number()
表示Number函数
- 简单判断:开头是否存在
new
,有new
—实例,无new
—函数 - 深度判断:使用关键字来判断,比如
typeof
、instanceof
,具体可以参考判断js数据类型的常用方法
new Number(123) instanceof Number; // true
Number('123') instanceof Number; // false
区别:
转换规则
1.如果是Boolean
类型,true
和false
将分别转换为1
和0
2.如果是数字值,只是简单的传入和返回
3.如果是null
,会返回0
4.如果是undefined
,返回NaN
5.如果是对象,则调用对象的valueOf()
方法,然后参考**string
转换成number
规则**
6.如果是字符串,遵守以下规则
string
转换成number
规则1.如果字符串只包含数字,则转换为十进制数值2.如果包含有效浮点数,则会转换对应浮点数值3.如果字符串包含有效的进制格式,则会转换成对应的十进制4.如果字符串前面为0
,会被忽略5.如果字符串是空的,则转换成0
6.如果字符串中包含上述格式之外的字符,则转换成NaN
// 整数
Number('123') // 123
// 浮点数
Number('12.5') // 12.5
// Boolean
Number(true) // 1
Number(false) // 0
// null
Number(null) // 0
// undefined
Number(undefined) // NaN
// string
// 十六进制
Number('0xA') // 10
// 二进制
Number('0b101') // 5
// 八进制
Number('056') // 56,0被忽略,默认为十进制
// 无效进制
Number('0xDFI') // NaN
// ' '
Number(' ') // 0
// 其他
Number('123blue') // NaN
Number('blue') // NaN
控制台输出结果
parseInt(string, radix)
string
:表示被转换的类型,一般为string
类型radix
:进制值,默认为十进制
MDN的解释为:
string
要被解析的值。如果参数不是一个字符串,则将其强制转化为字符串。字符串开头的空白符将会被忽略。
radix
可选从
2
到36
的整数,表示进制的基数。如果超出这个范围,将返回NaN
。假如radix
未指定或者为0
,除非数字以0x
或0X
开头(此时假定为十六进制16
),否则假定为10
(十进制)。
转换规则:
1.从左至右解析,直到遇到非数字字符
2.若后面有值,会忽略前面的空格和0
3.如果第一个非空格的值不是数字或者负号,返回NaN
4.空字符串会转换成NaN
5.如果是浮点数,会舍弃小数点后面的数
6.若是有效的十六进制,前面的0
是不会被忽略的
7.使用进制转换时,最好传入radix
(按x进制转换),否则很有可能解析不成功,因为parseInt()
不会自动识别此为几进制数
parseInt('123') // 123
// 浮点数
parseInt('12.56') // 12
// 空格
parseInt(' ') // NaN
// '0'
parseInt('0') // 0
// 0+num
parseInt('0123') // 123
// ' '+num
parseInt(' 123') // 123
// num+str
parseInt(' 123Nmu') // 123
// num+str
parseInt(' num90') // NaN
// 十六进制
parseInt('0xF') // 15
// 八进制 056:46
parseInt('056') // 56,0被忽略
parseInt('056', 8) // 46
// 二进制 0b101:5
parseInt('0b101') // 0
parseInt('0b101', 2) // 0,还是按照字符串解析
parseInt('101', 2) // 5
控制台输出结果
关于进制解析
从控制台输出结果可以得出的结论是:如果不传第二个参数,只会十六进制会被解析成功,其他进制会当作string转换处理。
《javascript高级程序设计》(第6版)书中是这样子解释的:
在使用parseInt()解析把八进制字面量的字符串时,ECMAScript3和5存在分歧。例如:
// ECMAScript3认为是56(八进制),ECMAScript5认为是70(十进制)
var num = parseInt('070')
为了消除上诉困惑,为parseInt()提供第二个参数:转换时使用的基数(即多少进制),为了避免错误的解析,我们建议无论什么情况都明确指定基数
题外之话:此书虽然出版时间较早,但是书里面的知识都比较经典,技术也许更新迭代很快,但是万变不离其宗,毕竟参考书中的建议,解析进制数时,是不会出错的(个人的一点小见解)
parseFloat(string)
与parseInt()
解析规则类型,区别在于parseFloat()
可以解析浮点数,关于浮点数的解析规则为:
第一个小数点是有效的,第二个小数点无效
parseFloat('123.456.78'); // 123.456
与parseInt()的区别:
1.可以转换浮点数
2.前导数0
始终会被忽略
3.只能解析十进制数,其他进制会按照string规则解析
4.如果一个值没有小数点或者小数点后都是0
,会解析会整数
parseFloat('0xF'); // 0
parseFloat('0b101'); // 0
parseFloat('056'); // 56
parseFloat('0abc'); // 0
// 科学计数法
parseFloat('3.125e7'); // 31250000
控制台输出结果
最后
整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。
有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享
部分文档展示:
文章篇幅有限,后面的内容就不一一展示了
有需要的小伙伴,可以点下方卡片免费领取