经常看到这个面试题:
- 为什么 [‘1’, ‘7’, ‘11’].map(parseInt) 返回 [1, NaN, 3] - 掘金
- Why [‘1’, ‘7’, ‘11’].map(parseInt) returns [1, NaN, 3] in Javascript
想必大家已经非常熟悉Map的原理,因为:
map(callback, [thisArg])方法:
- 接受一个回调函数
callback,返回一个新的数组- 返回的数组的元素的值为调用
callback函数所返回的值(原数组有几个元素,就调用几次callback)callback接受 3 个参数:
- currentValue:当前正在处理的数组元素的值
- index:当前正在处理的数组元素的索引
- arr:调用
map方法的数组
而parseInt接收两个参数:string值和radix进制值:
- string:被解析的字符串(前后空格会被忽略,若不是字符串,则转换成字符串)
- radix:指定
string(第一个参数)的基数(2~36,即2 进制~36进制),若不传或传0,则string(第一个参数)以10 进制来解析
所以:
['1', '7', '11'].map(parseInt); => [1, NaN, 3]
// 第一次迭代: val = '1', index = 0, array = ['1', '7', '11']
parseInt('1', 0, ['1', '7', '11']); => 1 因为 radix 为 0 ,所以 string 按照 10 进制 处理,返回 10 进制数 1
// 第二次迭代: val = '7', index = 1, array = ['1', '7', '11']
parseInt('7', 1, ['1', '7', '11']); => NaN 因为 radix 为 1,不在 2~36 范围,直接返回 NaN
// 第三次迭代: val = '11', index = 2, array = ['1', '7', '11']
parseInt('11', 2, ['1', '7', '11']); => 3 因为 radix 为 2(二进制),所有 11 为3。
[1, NaN, 3]并不是我们预期的值,今天我们反其道而行,写一个unary一元函数,使[‘1’,‘7’,‘11’] map之后输出[1,7,11];
我们第一时间想到,只将回调函数的currentValue传去给parseInt方法:
['1','7','11'].map(function(currentValue,index,arr){
return parseInt(currentValue);
})
(3) [1, 7, 11]
为了通用性,写一个闭包函数,抽象出一个unary方法:
const unary = (fn)=> fn.length === 1 ? fn: (currentValue)=>fn(currentValue);
['1','7','11'].map(unary(parseInt))

参考资料