前言
[‘1’, ‘2’, ‘3’].map(parseInt),这看上去,好像就是遍历1,2,3然后将他们都进行parseInt,所以脑海中的答案大概可能是1,2,3,但这是错误的,这里面有一个坑,涉及到parseInt的参数以及规范的问题
这也是面试题中常见的一道题目
接下来让我们搞清楚其运作原理
map
map方法是ES6新增的数组方法,这是MDN上的map语法
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
可以看到,map接收一个参数,这参数是一个回调函数,并且这个回调函数一共可以接收三个参数,其中第一个参数代表当前被处理的元素,而第二个参数代表该元素的索引,第三个参数为方法调用的数组。
map先看到这里,接着看parseInt
parseInt
这道题中,了解parseInt才是解题的关键,这是MDN上parseInt的语法
parseInt(string, radix)
可以看到parseInt是接收两个参数的,这里两个参数就是问题所在,平时我们使用的parseInt,通常都是使用一个参数,所以来看看两个参数分别代表什么
第一个参数:要被解析的值。如果参数不是一个字符串,则将其转换为字符串(使用 ToString 抽象操作)。字符串开头的空白符将会被忽略。
第二个参数:从 2 到 36,表示字符串的基数。例如指定 16 表示被解析值是十六进制数。请注意,10不是默认值!
注意: parseInt的规范
然后要注意的是:如果 radix 是 undefined、0或未指定的,JavaScript会假定以下情况:
- 如果输入的 string以 "0x"或 “0x”(一个0,后面是小写或大写的X)开头,那么radix被假定为16,字符串的其余部分被当做十六进制数去解析。
- 如果输入的 string以 “0”(0)开头, radix被假定为8(八进制)或10(十进制)。具体选择哪一个radix取决于实现。ECMAScript 5 澄清了应该使用 10 (十进制),但不是所有的浏览器都支持。因此,在使用 parseInt 时,一定要指定一个 radix。
- 如果输入的 string 以任何其他值开头, radix 是 10 (十进制)。
也就是说,当radix为0时,并且输入的string不以"0x"或"0"开头,这时radix默认为10(十进制)
然后当radix小于2或大于36时,或第一个非空格字符不能转换为数字,返回NaN
解题
那么回到题目,[‘1’, ‘2’, ‘3’].map(parseInt),可以看到map方法接受的回调函数参数在这里其实就是parseInt,而parseInt是接收两个参数的,所以parseInt需要map提供两个参数,而map的前两个参数一个为当前处理元素,一个为当前处理元素下标,所以执行步骤应该如下
parseInt('1', 0) // radix为0时,且string参数不以“0x”和“0”开头时,按照10为基数处理。这个时候返回1
parseInt('2', 1) // radix为1时,radix小于2,所以返回NaN
parseInt('3', 2) // radix为2时,2进制数表示的数中,最大值小于3,无法解析,返回NaN
其实只要知道了parseInt会接收map的前两个参数,而不是一个参数,这道题目就解决了一半了
然后要知道这个parseInt的一些规范,这道题目就解决了
总结
那么再解决一下这道题目,看看是否能成功解决,成功解决就代表你理解了
[‘3’,‘2’, ‘1’].map(parseInt)的答案是多少?
答案是:3, NaN, 1
其实解题过程还是一样
parseInt('3', 0) // radix为0时,字符串不以"0x"和"0"开头时,radix默认为10进制,所以输出为3
parseInt('2', 1) // radix小于2时,返回NaN
parseInt('1', 2) // radix为2时,以2进制处理1,所以返回1