记得之前在一篇关于面试题目的文章中看到了这样的一个题目
['11','11','11','11'].map(parseInt)
得到的结果是什么?
对map和parseInt方法熟悉的同学,马上就能给出答案。如果跟我一样不太熟悉的那就先运行一下代码:
['11','11','11','11'].map(parseInt)
//=> [ 11, NaN, 3, 4 ]
结果是[11, NaN, 3, 4]
,如果你没有答对就跟着我一起看看为什么吧!
首先搜索一下在MDN web doc上对map的介绍:
map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
参数:
callback
生成新数组元素的函数,使用三个参数:
currentValue
callback 的第一个参数,数组中正在处理的当前元素。
index
callback 的第二个参数,数组中正在处理的当前元素的索引。
array
callback 的第三个参数,map 方法被调用的数组。
thisArg
可选的。执行 callback 函数时 使用的this 值。
从map的参数介绍中,我们知道map接收一个回调函数和一个回调的执行上下文。这里parseInt
就是这个回调函数,它接收了三个参数分别是currentValue
、index
、array
。
现在我们再了解一下parseInt
parseInt() 函数解析一个字符串参数,并返回一个指定基数的整数 (数学系统的基础)。
参数
string
要被解析的值。如果参数不是一个字符串,则将其转换为字符串(使用ToString抽象操作)。字符串开头的空白符将会被忽略。
radix
一个介于2和36之间的整数(数学系统的基础)
,表示上述字符串的基数。比如参数"10"表示使用我们通常使用的十进制数值系统。始终指定此参数可以消除阅读该代码时的困惑并且保证转换结果可预测。当未指定基数时,不同的实现会产生不同的结果,通常将值默认为10
看了parseInt的第二个参数介绍,答案就一目了然。下面我们把题目分解一下:
parseInt('11', 0) // 11 (第二个参数为0和为null或者false的效果一样,当作没有指定基数,默认为10),所以结果为11
parseInt('11', 1) // NaN (基数是2~36之间的整数,没有1基数,所以结果为NaN)
parseInt('11', 2) // 3
parseInt('11', 3) // 4
那如果想让['11','11','11','11'].map(parseInt)
得到[11,11,11,11]
,我们可以实现一个柯里函数解决。
function curry(fun) {
return function(arg) {
return fun(arg);
}
}
['11', '11', '11', '11'].map(curry(parseInt))
// => [11,11,11,11]
curry
的操作:接收一个函数,返回一个只接收一个参数的函数。这样我们就可以让parseInt只接收一个currentValue
,默认去用10为基数进行转换。