看完《你不知道的JavaScript(中册)》强制类型转换一章后,发现一个好玩的题目
问题
console.log(parseInt( 1/0, 19 ))
// 18
你没看错,结果是18 😂.
又想起之前的一道网红题
为什么
['1', '7', '11'].map(parseInt)返回[1, NaN, 3]
这些看似莫名其妙的结果,其中隐含的就是我们对 parseInt 缺乏进一步的了解。书上已经给出了解析,这里我做一个稍微的提炼,分享给大家。
那道网红题网上有各种解析,大家可以自行搜索查看。这里我主要解析文章开始的那道题。
parseInt
parseInt用于将字符串强制类型转换为数字。解析允许字符串中含有非数字字符,解析按从左到右的顺序,如果遇到非数字字符就停止。而转换不允许出现非数字字符,否则会失败并返回 NaN。
console.log(parseInt('10px'))
console.log(parseInt('width10px'))
// 10
// NaN
基本用法没什么好分析的,我们看下一个 🌰
console.log(parseInt('12'))
console.log(parseInt('12', 2))
console.log(parseInt('12', 5))
// 12
// 1
// 7
上面的代码中, parseInt 加入了第二个参数,看过网红题解析的同学应该都知道第二个参数表示基数,即第一个参数基于几进制进行解析。
注意点一
基数的范围为2~36,如果第一个参数的字符无法使用基数解析,则停止解析。如果第二个参数不在2~36范围中,则 parseInt直接返回NaN。
上面的例子中, parseInt(12, 2) 的结果为 1 ,原因是第二个字符 2无法被解析成二进制值,所以中断解析,返回 1。
再看一下第一个参数完全无法解析和基数超出范围的情况
console.log(parseInt('12', 1))
// NaN
console.log(parseInt('34', 2))
// NaN
上面的例子没什么好分析的,结合注意点一看就懂。😁
说了这么多,还没有进入正题,文章开头的题目是为什么
进入正题
注意点二
parseInt是用于解析字符串的!如果第一个参数传入非字符串,那么它会被自动转换成字符串再进行解析。
再看一遍文章开始的题目
console.log(parseInt( 1/0, 19 ))
// 18
首先1/0结果为 Infinity,转换成字符串就是 'Infinity' , 所以上面的代码可以看成
console.log(parseInt('Infinity', 19))
等等,大家第一反应可能是
第一个参数是非数字,结果应该是NaN
大家别忘了,第二个参数是 19,此时第一个参数按 19 进制解析的。19进制 什么概念... A B C D E F G H I是有意义的,分别表示 10 11 12 13 14 15 16 17 18。
有没有种恍然大明白的感觉 😄
解析
Infinity 按 19 进制解析,第一个字符 I 被解析成 18,第一个字符 n 无法被解析,中断执行,返回18。
嗯... 知道答案后,顿时索然无味
什么,还不够? 那再来看几道题
parseInt( 0.0000008 );
parseInt( false, 16 );
parseInt( parseInt, 16 );
parseInt( "0x10" );
// 8
// 250
// 15
// 16
索然无味之后是不是又一顿抽搐😄,肯定又在想 parseInt真的令人绝望。
但是!parseInt表示这个锅我不背,需要注意的点上面都已经列出来了,剩下的就是JavaScript其他坑的问题了。
这里还是对上面的4道题做一个简单的提示吧,大家可以根据提示自行理解,有问题欢迎留言讨论。
console.log(0.0000008.toString())
// 8e-7
console.log(false.toString())
// 'false'
console.log(parseInt.toString())
// function parseInt() { [native code] }
// 0x开头的数字会被按16进制解析