🍉一文辨析Number()函数、parseInt()函数与parseFloat()函数

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 🍉一文辨析Number()函数、parseInt()函数与parseFloat()函数

前言


在实际开发中,我们经常遇到将其他类型的值转换为Number类型的情况。一般可以通过Number()函数、parseInt()函数以及parseFloat()函数进行转换,但是它们三者使用起来还是有一定区别和注意事项的。这篇文章我们就来聊聊这三个函数。


1.Number()函数


Number()函数可以用于将任何类型转换为Number类型,它在转换时遵循下列规则。


  1. 如果是数字,则按照对应的进制数据格式,统一转换为十进制并返回。


Number(10); // 10
Number(010); // 8
Number(0x10); // 16
复制代码


  1. 如果是Boolean类型的值,true将返回为“1”,false将返回“0”


Number(true); // 1
Number(false); // 0
复制代码


  1. 如果值为undefined,则返回"NaN"。


Number(undefined); // NaN
复制代码


  1. 如果值为null,则返回“0”


Number(null); // 0
复制代码


  1. 如果值为字符串类型,则遵循下列规则。


  • 如果该字符串只包含数字,则会直接转换成十进制数,如果前面有0,则会直接忽略这个0。


Number('21'); // 21
Number('021'); // 21
复制代码


  • 如果字符串是有效的浮点数形式,则会直接转换成对应的浮点数,前置的0会被清空,只保留一个。


Number('0.12'); // 0.12
Number('0.012'); // 0.12
复制代码


  • 如果字符串是有效的十六进制形式,则会转换为对应的十进制数值。


Number('0x12'); // 18
Number('0x21'); // 33
复制代码


  • 如果字符串是有效的八进制形式,则不会按照八进制转换,而是直接按照十进制转换并输出,因为前置的0会被直接忽略。


Number('010'); // 10
Number('0020'); // 20
复制代码


  • 如果字符串为空或为连续的空格,则会转换为0


Number(''); // 0
Number('  '); // 0
复制代码


  • 如果字符串不是上述5种情况之一,则返回“NaN”


Number('123a'); // NaN
Number('a1.1'); // NaN
复制代码


  1. 如果值为对象类型,则会调用对象的alueOf()函数获取返回值,并将返回值按照上述步骤重新判断能否转换为Number类型,如果都不满足,则会调用对象的toString()函数获取返回值,并将返回的值重新按照上述步骤重新判断,如果还不能转换成Number类型则返回"NaN"


let obj = {
    age: 21,
    valueOf: function() {
        return this.age;
    },
    toString: function() {
        return 'good';
    }
};
Number(obj); // 21
复制代码


2. parseInt()函数


parseInt()函数用于解析一个字符串,并返回指定的基数对应的整数值。 语法格式如下:


parseInt(string, radix);
复制代码


radix表示的是进制转换的基数,数据范围是2~36

在使用parseInt()函数将字符串转换成整数时,需要注意以下5点:


  1. 非字符串类型转换为字符串类型


如果传入的参数是非字符串类型的情况,则需要将其优先抓换成字符串类型,即使传入的是整型数据


parseInt('0x12', 16); // 18
parseInt(0x12, 16); // 24(0x12要先转换为'18')
复制代码


  1. 数据截取的前置匹配原则


parseInt()函数在做转换时,会从字符串的第一个字符开始匹配,如果处于基数指定的范围,则保留并继续往后匹配满足条件的字符,直到某个字符不满足基数指定的数据范围,则从该字符开始,舍弃后面的全部字符。


parseInt('fg123', 16); // 15(舍弃掉g123)
复制代码


如果遇到的字符串是以“0x”开头的,那么按照十六进制处理时,会计算后面满足条件的字符串;如果按照十进制处理,则会直接返回“0”。


parseInt('0x12', 16); // 18 = 16 + 2
parseInt('0x12', 10); // 0
复制代码


如果传入的字符串中涉及算术运算,则不执行;如果传入的参数是算术表达式,则会先运算完成得到结果,再参与parseInt()函数的计算。


parseInt(15 * 3, 10); // 45
parseInt('15 * 3', 10); // 15
复制代码


  1. 对包含字符e的不同数据的处理差异


parseInt(6e3, 10) ; // 6000
parseInt(6e3, 16) ; // 24576 (6 * 16^3)
parseInt('6e3', 10) ; // 6 ('e3'舍弃)
parseInt('6e3', 16) ; // 1763 (6*16^2 + 14*16 + 3)
复制代码


  1. 对浮点型数的处理


如果传入的值是浮点型数,则会忽略小数点及后面的数,直接取整。


parseInt('6.01', 10) // 6
parseInt('6.99', 10) // 6
复制代码


  1. map()函数与parseInt()函数的隐形坑


设想一个场景,存在一个数组,数组中的每一个元素都是Number类型的字符串['1','2','3','4'],如果我们想要将数组中的元素全部转换为整数,我们该怎么做呢? 你可能会这样处理:


let arr = ['1','2','3','4'];
let result = arr.map(parseInt);
console.log(result);
复制代码


最终得到的结果确实[1,NaN,NaN,NaN]。 这其实是一个隐形坑,下面的两段代码其实是等效的。


arr.map(parseInt);
arr.map((val, index)=> {
    return parseInt(val, index)
})
复制代码


parseInt()函数接受的第二个参数实际为数组的索引值,所以实际处理过程如下:


parseInt('1', 0); // 1
parseInt('2', 1); // NaN
parseInt('3', 1); // NaN
parseInt('4', 1); // NaN
复制代码


正确的处理方式应该是这样:


let arr = ['1','2','3','4'];
let result = arr.map((val)=> {
    return parseInt(val, 10)
})
console.log(result); // [1,2,3,4]
复制代码


3.parseFloat()函数


parseFloat()函数用于解析一个字符串,返回对应的浮点数,如果给定值不能转换为数值,则会返回“NaN”。


它与parseInt()函数相比,没有进制的概念,所以在转换时简单些,但是仍有一些需要注意的:


  1. 如果在解析过程中遇到了正负号、数字0~9、小数点或者科学计数法(e/E)以外的字符,则会忽略从该字符开始至结束的所有字符。其中,正负号必须出现在字符的第一位,而且不能连续出现。


parseFloat('+1.2'); // 1.2
parseFloat('++1.2'); // NaN
复制代码


  1. 字符串前面的空白符会直接忽略,如果第一个字符无法解析,直接返回“NaN”


parseFloat(' 1.2'); // 1.2
parseFloat('f1.2'); // NaN
复制代码


  1. 对于字符串中出现的e,会先进行科学计数法的运算,然后转换成浮点型数返回


parseFloat('4e3'); // 4000
复制代码


  1. 对于小数点,第二个小数点是无效的,后面的字符都会被忽略


parseFloat('11.20'); // 11.2
parseFloat('11.2.2'); // 11.2
复制代码


总结


这三个函数都能用于Number类型的转换,但是在处理方式上还是有一些差异的。


  • Number()函数转换的是传入的整个值,整个值不能被完整转换,则会返回“NaN”。
  • parseFloat()函数在解析小数点是,会把第一个小数点当作有效字符,而parseInt()函数遇到小数点则直接停止。
  • parseFloat()函数在解析时没有进制的概念,而parseInt()函数在解析时会依赖于传入的基数做数值转换。
相关文章
|
7月前
|
关系型数据库 MySQL
【随手记】MySQL中ROW_NUMBER()、RANK()和DENSE_RANK()函数的用法
【随手记】MySQL中ROW_NUMBER()、RANK()和DENSE_RANK()函数的用法
216 1
|
Oracle 关系型数据库
Oracle中decode 以及ROW_NUMBER() OVER() 函数等其它相关函数用法
Oracle中decode 以及ROW_NUMBER() OVER() 函数等其它相关函数用法
141 0
|
8月前
ROW_NUMBER() OVER()函数用法详解 (分组排序 例子多)
ROW_NUMBER() OVER()函数用法详解 (分组排序 例子多)
116 0
|
8月前
|
SQL 关系型数据库 MySQL
Greenplum【SQL 02】ROW_NUMBER编号函数使用方法举例
Greenplum【SQL 02】ROW_NUMBER编号函数使用方法举例
172 0
|
存储 JavaScript 前端开发
【JS交互埋坑】事件函数自动将数字字符串String转为数值Number
【JS交互埋坑】事件函数自动将数字字符串String转为数值Number
94 0
|
存储 JavaScript 前端开发
【JS交互埋坑】事件函数自动将数字字符串String转为数值Number
【JS交互埋坑】事件函数自动将数字字符串String转为数值Number
121 0
|
关系型数据库 MySQL
MySQL - ROW_NUMBER() OVER()函数用法详解(分组排序)
MySQL - ROW_NUMBER() OVER()函数用法详解(分组排序)
1000 0
MySQL - ROW_NUMBER() OVER()函数用法详解(分组排序)
|
机器学习/深度学习 人工智能 Oracle
在Oracle中,TO_CHAR()、TO_NUMBER()和TO_DATE()函数的使用方法以及作用
在Oracle中,TO_CHAR()、TO_NUMBER()和TO_DATE()函数的使用方法以及作用
539 0
|
SQL Oracle 关系型数据库
Oracle-分析函数之排序后顺序号row_number()
Oracle-分析函数之排序后顺序号row_number()
112 0
|
SQL 监控 数据库
网站流量日志分析--统计分析--分组 topN--row_number over 函数使用|学习笔记
快速学习网站流量日志分析--统计分析--分组 topN--row_number over 函数使用
277 0
网站流量日志分析--统计分析--分组 topN--row_number over 函数使用|学习笔记