转载于公众号大迁世界——《请别再使用parseInt()了》一文
Number()和parseInt()的区别
当Number()
和parseInt()
的参数为字符串时
Number()
函数评估整个字符串并将其转换为数字,如果这个字符串不是一个数字,就返回NaN
Number() // 0
Number('') // 0
Number('abc') // NaN
Number('abc123') // NaN
parseInt(string,[radix])
函数会尝试在传递的字符串中找开头的整数,将其转换为传递的进制,进制默认为10,如果开头不是整数,则返回NaN
意思是,刚传递'5e2'
这样的字符串,parseInt
会在看到'e'
时停止,因此只会返回'5'
,而Number则评估整个字符串并返回正确的值
可以发现这两个函数之间有一些不同:Number()评估整个字符串,parseInt()找开头的整数
Number('a'); // NaN
Number('1'); // 1
Number('5e2'); // 500
Number('16px'); // NaN
Number('3.2'); // 3.2
Number('px16'); // NaN
parseInt('a'); // NaN
parseInt('1'); // 1
parseInt('5e2'); // 5
parseInt('16px'); // 16
parseInt('3.2'); // 3
parseInt('px16'); // NaN
性能上的区别
假设有这样一个简单的函数,循环一亿次,并接受回调,现在让我们调用这个函数两次,第一次使用Number,第二种使用parseInt
function runBench(cb) {
const start = new Date();
for (let i = 0; i < 100000000; i++) {
cb();
}
const end = new Date();
console.log(`It took ${end - start} ms`);
}
const process1 = () => Number('3.2');
const process2 = () => parseInt('3.2', 10);
runBench(process1); // It took 140 ms
runBench(process2); // It took 4546 ms
实际情况下当然不可能运行1亿次循环,这里是为了让两个函数之间的性能差异变得明显。还有一点是,当你在同一个函数的多个地方使用parseInt时,最后结果可能就直接计算总和了
那我们应该一直避免使用parseInt吗?
并非如此,在某些用例中使用parseInt()
是有益的
比如你想从浮点数中推断出一个整数,那么Number()
不能实现,而parseInt()
比Math.round()
快50%
还有,如果想将一个带有像素的字符串转换为数字,比如'32px'
转换为32
,那么应该使用parseInt()
,但大多数时候还是推荐使用Number()
更多基准测试
因为还有其他方法可以将字符串转换为数字,下面我将使用parseFloat()
和一元运算符添加测试,请看结果:
function runBench(cb) {
const start = new Date();
for (let i = 0; i < 100000000; i++) {
cb();
}
const end = new Date();
console.log(`It took ${end - start} ms`);
}
const process1 = () => Number('1');
const process2 = () => parseInt('1', 10);
const process3 = () => parseFloat('1');
const process4 = () => +'1';
runBench(process1); // It took 70 ms
runBench(process2); // It took 4552 ms
runBench(process3); // It took 5082 ms
runBench(process4); // It took 412 ms
可以看到,使用Number()仍然是最快的转换方法