一:题目
- 今天讲讲
parseInt
,之前曾看到过这么一道题:
['1', '2', '3'].map(parseInt)
- 输出什么? 有些人得出的答案可能是:[1, 2, 3],这其实是一个 错误 答案。
- 我们看看正确答案是什么,在控制台打印输出下:
他输出的居然是:[1, NaN, NaN]
,有些人就很好奇它为什么输出的是[1, NaN, NaN]
而不是[1, 2, 3]
。
二: 重新审题
['1', '2', '3'].map(parseInt)
map(parseInt)
可能会有很多疑问,这是什么写法?这其实是简写,让我们看看其他例子- 所以此处简写
['1', '2', '3'].map(parseInt)
- 完整写法如下
['1', '2', '3'].map((v, i, arr) => parseInt(v, i))
- 所以此处简写
map()
:里面是个回调函数,三个参数:分别是当前值(v)
,下标(i)
,原始数组(arr)
- 执行顺序:
['1', '2', '3'].map((v, i, arr) => parseInt(v, i))
,依次输出:parseInt('1', 0) // 1
parseInt('2', 1) // NaN
parseInt('3', 2) // NaN
三:parseInt
在这有人可能或好奇为什么第一个输出的是
1
,第二个和第三个是NaN
,这我们就正式进入今天的主题
-
什么是parseInt?
MDN: parseInt(string, radix) 将一个字符串
string
转换为radix
进制的整数,radix
为介于2-36之间的数。最后都是以十进制形式返回。所以
parseInt
的第二个参数是进制,但它也说明了进制时介于2~36
之间的数 -
排除疑惑
- 所以根据
parseInt
的第二个参数进制范围,我们就能知道parseInt('2', 1)
为什么等于NaN
- 那为什么
parseInt('1', 0)
等于1
呢? 来自MDN关于parseInt
的截图 ,所以0会被当做10进制来算,所以parseInt('1', 0)
等于1
- 那为什么
parseInt('3', 2)
等于NaN
呢? 在回答这个问题之前我们先了解下进制,来自百度百科截图
所以
parseInt
的第一个参数string
要小于第二个参数radix
,所以parseInt('3', 2)
等于NaN
;-
根据上面的推断,我们再往里面多加一些,具体来看看:
数组'3',...'9'
之间对应的下标值就是2~8
,第一个参数都大于进制,所以都是NaN
-
那为什么第一个参数为
'10'
,进制为9
时,parseInt('10', 9)
输出的不是NaN
,而是9
。- 根据前面对进制的描述,
9
进制表示的实数就是0~8
之间。第一个参数不管传入的是string
还是number
,他都会被挨个解析成字符串处理,所以在9
进制中'1'
和'0'
属于0~8
的实数
- 根据前面对进制的描述,
- 所以根据
-
运算
-
在不通过控制台怎么去自己算?
在回答这个问题之前先看下来自MDN的截图:注意:此处千万不要把
1*5^2 + 2*5^1 + 3*5^0
直接复制下来在控制台运算,不然计算出来的跟实际parseInt('123', 5)
算出来的结果不一样,至于为什么,因为^
是位运算符,其实在这表达的意思是几次方的意思,正确写法:1*Math.pow(5, 2) + 2*Math.pow(5, 1) + 3*Math.pow(5, 0)
-
我们看看是怎么计算的
他会把'123'
挨个解析字符串'1'
,'2'
,'3'
,然后分别乘以Math.pow(x, y)
;x: 是底数,在这的底数就是`parseInt`的第二个参数进制`radix` y: 是幂数,在这的幂数就是`parseInt`的第一个参数字符串 "从右往左" 的下标值
-
我们再多试几个
parseInt('4123', 5); // 538
4*Math.pow(5, 3) + 1*Math.pow(5, 2) + 2*Math.pow(5, 1) + 3*Math.pow(5, 0) // 538
parseInt('764', 8); // 500
7*Math.pow(8, 2) + 6*Math.pow(8, 1) + 4*Math.pow(8, 0); // 500
-
-
-
扩展
-
parseInt
的第一个参数string的的实数必须小于进制数?我们看看截图:
- 如图:
- 前两个解析正常,为什么第三个
parseInt('125', 5)
输出为7
,这就不符合上面的计算公式,后来发现它自动把最后的5
给删除了,输出的其实是parseInt('12', 5)
,这样输出就是等于7
。 - 为什么第四个输出是
NaN
,因为参数string
已5
开头,不符合进制所属数,所以直接返回NaN
。 - 最后一个直接把
55
删除了,最终解析成parseInt('1', 5)
,输出1
- 前两个解析正常,为什么第三个
- 如图:
-
结论:
- 如果第一个参数
string
的第一个值就大于等于第二个参数radix
,那么直接返回NaN
- 如果第一个参数
string
的第一个值符合条件,其他值不符合条件,那么不符合条件的值到最后会被忽略,然后进行计算
- 如果第一个参数
-
四:课外题
1. ['10', '10', '10', '10'].map(parseInt); //输出什么
2. 1*5^2 + 2*5^1 + 3*5^0 // 输出什么,你知道它是如何运算的?
第一次写博客,如有瑕疵,还请各位大佬多多海涵