目录


在实际开发中,我们经常遇到将其他类型的值转换为
Number类型的情况。一般可以通过Number()函数、parseInt()函数以及parseFloat()函数进行转换,但是它们三者使用起来还是有一定区别和注意事项的。这篇文章我们就来聊聊这三个函数。
一、Number()函数
Number()函数可以用于将任何类型转换为Number类型,它在转换时遵循下列规则。
1、如果是数字,则按照对应的进制数据格式,统一转换为十进制并返回。
Number(10); // 10
Number(010); // 8
Number(0x10); // 16
2、如果是Boolean类型的值,true将返回为“1”,false将返回“0”
Number(true); // 1
Number(false); // 0
3、如果值为undefined,则返回"NaN"。
Number(undefined); // NaN
4、如果值为null,则返回“0”
Number(null); // 0
5、如果值为字符串类型,则遵循下列规则。
❶如果该字符串只包含数字,则会直接转换成十进制数,如果前面有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
6、如果值为对象类型,则会调用对象的valueOf()函数获取返回值,并将返回值按照上述步骤重新判断能否转换为Number类型,如果都不满足,则会调用对象的toString()函数获取返回值,并将返回的值重新按照上述步骤重新判断,如果还不能转换成Number类型则返回"NaN"。
let obj = {
age: 21,
valueOf: function() {
return this.age;
},
toString: function() {
return 'good';
}
};
Number(obj); // 21
二、parseInt()函数
parseInt()函数用于解析一个字符串,并返回指定的基数对应的整数值。 语法格式如下:
parseInt(string, radix);
- string:必需参数,表示要被解析的字符串。如果参数不是一个字符串,则会先将其转换为字符串
- radix:可选参数,表示要解析的数字的基数(进制)即进制转换的基数,取值范围是2到36之间的整数。
简单示例
parseInt("123"); // 返回123 (默认十进制)
parseInt("123", 10); // 返回123 (明确指定十进制)
parseInt("0xFF", 16); // 返回255 (十六进制转换)
parseInt("077"); // 返回77 (ECMAScript 5+中忽略前导0)
parseInt("101", 2); // 返回5 (二进制转换)
工作原理
1、字符串处理:parseInt()会先将其第一个参数转换为字符串(如果不是字符串的话),然后解析这个字符串。
2、解析过程:函数会从字符串的开头开始解析,直到遇到一个无法识别为数字的字符为止,返回已解析的部分。
3、空格处理:字符串开头的空格会被自动忽略。
4、进制推断:当没有提供radix参数或radix为0时,parseInt()会根据字符串的内容自动判断基数
- 以"0x"或"0X"开头:解析为十六进制数
- 以"0"开头:可能解析为八进制或十进制(取决于浏览器实现)
- 其他情况:解析为十进制
在使用parseInt()函数将字符串转换成整数时,需要注意以下10点:
1、始终指定radix参数
由于不同浏览器对以"0"开头的字符串处理方式不同(有的解析为八进制,有的解析为十进制),最佳实践是始终明确指定radix参数。
// 不推荐 - 结果可能因浏览器而异
parseInt("010");
// 推荐 - 明确指定基数
parseInt("010", 10); // 返回10
2、非字符串类型转换为字符串类型
如果传入的参数是非字符串类型的情况,则需要将其优先转换成字符串类型,即使传入的是整形数据。
parseInt('0x12', 16); // 18
parseInt(0x12, 16); // 24(0x12要先转换为'18')
3、非数字字符的处理
- 如果字符串的第一个字符不能被转换为数字,
parseInt()会返回NaN - 如果字符串中包含非数字字符,
parseInt()会从第一个非数字字符处停止解析,返回之前解析的数字部分。
parseInt("123abc"); // 返回123
parseInt("abc123"); // 返回NaN
parseInt("12.34"); // 返回12 (小数点不是数字字符)
4、数据截取的前置匹配原则
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
5、进制范围的限制
radix参数必须在2到36之间。如果超出这个范围,parseInt()会返回NaN
parseInt("11", 1); // NaN (基数太小)
parseInt("11", 37); // NaN (基数太大)
parseInt("11", 0); // 特殊情况,相当于未指定基数
6、特殊值的处理
null和undefined作为radix参数会被忽略- 负号会被正确处理
parseInt("-99", null); // 返回-99
parseInt("-99", 10); // 返回-99
parseInt("-FF", 16); // 返回-255
7、对包含字符e的不同数据的处理差异
对于会自动转为科学计数法的数字,
parseInt()会将科学计数法的表示视为字符串,可能导致意外结果。
parseInt(1000000000000000000000.5); // 返回1
// 等同于
parseInt('1e+21'); // 返回1
parseInt(0.0000008); // 返回8
// 等同于
parseInt('8e-7'); // 返回8
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)
注:parseInt(1000000000000000000000.5) 的执行结果是 1。原因如下:
1、参数隐式转换:parseInt 会先将参数转为字符串,1000000000000000000000.5 转换为字符串后为 "1e+21"(科学计数法表示)。
2、解析规则:parseInt 从字符串开头解析数字字符直到非数字字符(此处为 e),因此仅解析到 "1"。
3、返回值:最终将 "1" 转为整数 1。
注意:若需完整解析大数,建议使用 Number() 或保留小数位处理。
注:parseInt('8e-7') 的返回值是 8。
原因解析:
1、parseInt 的解析规则:
- 从字符串开头依次解析数字字符,直到遇到非数字字符(包括科学计数法的
e)时停止。 '8e-7'中,8是有效数字字符,但e会被视为非数字字符,因此解析终止于8。
2、科学计数法无效:
parseInt不会处理科学计数法(如'8e-7'实际表示8×10^-7),它只会解析连续的整数部分。
3、对比其他方法:
- 若需解析科学计数法,应使用
parseFloat('8e-7')或Number('8e-7'),此时会返回0.0000008。
总结:parseInt 的设计初衷是解析整数,因此会忽略非整数格式的字符(包括 . 和 e)。
8、对浮点型数的处理
如果传入的值是浮点型数,则会忽略小数点及后面的数,直接取整。
parseInt('6.01', 10) // 6
parseInt('6.99', 10) // 6
9、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]
最终得到的结果确实[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]
10. 与Number()的区别
parseInt()与Number()函数有重要区别:
-
parseInt()只解析整数部分,遇到非数字字符停止 -
Number()可以解析整数和浮点数,但遇到非数字字符会返回NaN
parseInt("123.45"); // 返回123
Number("123.45"); // 返回123.45
parseInt("123abc"); // 返回123
Number("123abc"); // 返回NaN
实际应用示例
1. 处理用户输入
let userInput = " 42px";
let num = parseInt(userInput.trim(), 10);
if (!isNaN(num)) {
console.log("解析后的数字:", num); // 输出: 解析后的数字: 42
} else {
console.log("无效输入");
}
2. 进制转换
// 十六进制转十进制
parseInt("FF", 16); // 返回255
// 二进制转十进制
parseInt("1010", 2); // 返回10
// 八进制转十进制
parseInt("17", 8); // 返回15
3. 数组处理
注意:当parseInt()用于map()等函数时,可能会产生意外结果,因为它会接收元素索引作为第二个参数。
// 不推荐 - 会产生意外结果
['1', '2', '3'].map(parseInt);
// 实际相当于 [parseInt('1',0), parseInt('2',1), parseInt('3',2)]
// 返回 [1, NaN, NaN]
// 推荐写法
['1', '2', '3'].map(num => parseInt(num, 10)); // 返回 [1, 2, 3]
▼总结
parseInt()是JavaScript中一个强大但需要谨慎使用的函数。为了确保代码的可靠性和跨浏览器一致性,请记住以下要点:
❶始终明确指定radix参数,避免浏览器间的差异。
❷了解自动字符串转换和科学计数法处理可能带来的意外结果。
❸注意非数字字符的处理方式,它与Number()函数不同。
❹在数组方法中使用时要小心,避免将索引误认为radix参数。
❺对于关键应用,考虑使用更严格的解析函数或库。
三、parseFloat()函数
parseFloat()函数用于解析一个字符串,返回对应的浮点数,如果给定值不能转换为数值,则会返回“NaN”。
它与parseInt()函数相比,没有进制的概念,所以在转换时简单些,但是仍有一些需要注意的:
1、如果在解析过程中遇到了正负号、数字0~9、小数点或者科学计数法(e/E)以外的字符,则会忽略从该字符开始至结束的所有字符。其中,正负号必须出现在字符的第一位,而且不能连续出现。
parseFloat('+1.2'); // 1.2
parseFloat('++1.2'); // NaN
2、字符串前面的空白符会直接忽略,如果第一个字符无法解析,直接返回“NaN”。
parseFloat(' 1.2'); // 1.2
parseFloat('f1.2'); // NaN
3、对于字符串中出现的 e,会先进行科学计数法的运算,然后转换成浮点型数返回。
parseFloat('4e3'); // 4000
注:parseFloat('4e3') 的解析结果是 4000。
解释:
parseFloat会解析字符串中的数字部分,支持科学计数法表示。4e3是科学计数法,表示 4 × 10³,即 4000。- 因此,
parseFloat将其转换为数值 4000。
如果字符串中包含非数字字符(如字母、符号等),parseFloat 会忽略它们并返回已解析的数字部分。
4、对于小数点,第二个小数点是无效的,后面的字符都会被忽略。
parseFloat('11.20'); // 11.2
parseFloat('11.2.2'); // 11.2
▼总结一哈
这三个函数都能用于Number类型的转换,但是在处理方式上还是有一些差异的。
- Number()函数转换的是传入的整个值,整个值不能被完整转换,则会返回“NaN”。
- parseFloat()函数在解析小数点是,会把第一个小数点当作有效字符,而parseInt()函数遇到小数点则直接停止。
- parseFloat()函数在解析时没有进制的概念,而parseInt()函数在解析时会依赖于传入的基数做数值转换。
✔参考资料▼
JavaScript 全局对象之parseInt()函数与parseFloat()函数
JS数据类型转换 ( parseInt() / parseFloat() 函数 | Number() 函数 | 运算符隐式转换 )

2054

被折叠的 条评论
为什么被折叠?



