你所不知道的Number()、parseInt()、parseFloat()转换细则

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情

为什么要写这篇文章

最近在阅读《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()相同

思维导图

个人习惯,每次记录一些东西喜欢先用思维导图,一个是简单直观,还有一个是缕清思路,见者不喜勿怪哈

image.png

Number(string)

区别于New Number()

new Number()表示Number实例Number()表示Number函数

  • 简单判断:开头是否存在new,有new—实例,无new—函数
  • 深度判断:使用关键字来判断,比如typeofinstanceof ,具体可以参考判断js数据类型的常用方法
new Number(123) instanceof Number; // true

Number('123') instanceof Number; // false

image.png

区别:

image.png

转换规则

  1. 如果是Boolean类型,truefalse将分别转换为10
  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

控制台输出结果

image.png

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

控制台输出结果

image.png

关于进制解析

从控制台输出结果可以得出的结论是:如果不传第二个参数,只会十六进制会被解析成功,其他进制会当作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

控制台输出结果

image.png

参考资料:

《javascript高级程序设计》(第6版)

MDN官网

往期相关文章

深入理解Number类型

判断js数据类型的常用方法

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容