为什么Array.from直接传parseInt与箭头函数包裹的运行结果不同
问题原因分析
首先我们先明确两个核心API的参数规则:
1. Array.from 映射函数的传参规则
Array.from() 的第二个参数是可选的映射回调,遍历每一个元素时,会自动给这个回调传入三个参数:
- 当前遍历到的元素值
- 当前元素的索引
- 正在遍历的原类数组/数组对象
2. parseInt 的真实参数规则
你存在一个认知误区:parseInt 并不仅仅接收1个参数,它的完整语法是 parseInt(string, radix):
- 第一个参数是要解析的字符串,必填
- 第二个参数是解析用的进制基数,可选,取值范围是2~36。如果不传该参数,parseInt会自动推断进制,推断规则存在很多隐形坑。
两种写法的差异拆解
第一种写法(正常运行)
let bb = Array.from(aa, (val) => parseInt(val));
这里你用箭头函数对parseInt做了一层包装,只把遍历得到的第一个参数「元素值」传给了parseInt,parseInt接收不到第二个参数,就会默认按10进制解析字符串,所以'1'、'2'、'3'都能被正常转成对应的整数,得到预期结果[1,2,3]。
第二种写法(结果异常)
let cc = Array.from(aa, parseInt);
这里你直接把parseInt作为映射函数传入,Array.from 会把遍历生成的三个参数全部传给parseInt,parseInt会自动取前两个参数使用,三次调用的实际传参分别是:
- 第一次遍历索引为0的元素'1':调用
parseInt('1', 0),基数为0时parseInt默认按10进制解析,返回1 - 第二次遍历索引为1的元素'2':调用
parseInt('2', 1),不存在1进制的合法表示,解析失败返回NaN - 第三次遍历索引为2的元素'3':调用
parseInt('3', 2),2进制只允许出现0和1,3是非法字符,解析失败返回NaN
所以最终得到的结果就是[1, NaN, NaN]。
最佳实践建议
使用parseInt时建议始终明确传入第二个进制参数10,避免自动推断带来的隐形问题,比如可以把代码优化为:
const cc = Array.from(aa, (val) => parseInt(val, 10))
如果确认要转换的都是十进制数字,也可以用更简单的写法:
const cc = Array.from(aa, Number)
Number作为转换函数只接收一个参数,不会有上述的多参数传参问题。
内容的提问来源于stack exchange,提问作者David542
相关产品推荐
相关产品推荐

