前言
在前端开发的面试中,经常会遇到一些看似简单,实则暗藏玄机的题目。其中, map 方法与 parseInt 函数的组合使用,就常常让不少求职者栽跟头。
问题
console.log(['1','2','3'].map(parseInt))
HR:请问这个输出什么?
我:这不就是一个简单的map函数吗,遍历字符串再转成数值类型。包输出1 2 3。
HR:回家吧孩子。
于是我连夜回去执行,发现是:1 NaN NaN
这是为啥啊?不符合逻辑啊???
我们不要寻求一步登天,来一步步分析。
Map
1. map 方法的工作机制
map 是数组的一个高阶函数,其功能是创建一个新数组,新数组中的每个元素都是原数组元素经过某种转换后得到的结果。它的语法如下:
const newArray = arr.map(callback(currentValue, index, array), thisArg);
-
回调函数(callback):这是为数组每个元素执行的函数,该函数会返回一个新值,它可以接收三个参数:currentValue:当前正在处理的数组元素。index:当前元素在数组中的索引。array:调用map方法的原始数组。
-
thisArg(可选):在执行callback函数时使用的this值。
我们可以看到,map函数接收一个 回调函数(callback) 作为参数。这个回调函数会针对数组中的每个元素执行一次,然后返回一个新数组,新数组中的元素是原数组元素经过回调函数处理后的结果。
那我们可以看到,这里的map接收了一个array的内置函数parseInt。
ParseInt
-
MDN 给出
parseInt的官方定义是:parseInt(string, radix) 解析一个字符串并返回指定基数的十进制整数,radix是 2-36 之间的整数,表示被解析字符串的基数。 -
语法:
parseInt(string, radix);
- 参数:
-
string:要被解析的值。如果参数不是一个字符串,则将其转换为字符串。字符串开头的空白符将会被忽略。 -
radix(可选):从2到36的整数,表示进制的基数。例如指定
16表示被解析值是十六进制数。如果超出这个范围,将返回NaN。假如指定0或未指定,基数将会根据字符串的值进行推算。
- 返回值:
(1)从给定的字符串中解析出的一个整数。
(2)当出现以下任一情况时,返回NaN:
radix小于2或大于36.- 第一个非空格字符不能转换为数字。
介绍完两种函数之后,我们再回头看看原题
题目详解
console.log( ['1','2','3'].map(parseInt) )
map 方法在调用 parseInt 时,会依次传入三个参数:当前元素、当前索引和原数组。而 parseInt 函数只接受两个参数:字符串和进制数。因此,实际的调用过程如下:
// map第一个参数传入的是字符串,第二个参数是进制数,第三个参数是原数组
// 所以 parseInt 会被执行三次,每次传入的参数分别是:
parseInt('1',0,['1', '2', '3'])
parseInt('2',1,['1', '2', '3'])
parseInt('3',2,['1', '2', '3'])
// parseInt中第二个参数是进制数
- 对于 parseInt('1', 0) ,当 radix 为 0 时, parseInt 会默认将其视为 10 进制,所以结果是 1。
- 对于 parseInt('2', 1) ,由于 1 进制是不存在的,所以结果是 NaN 。
- 对于 parseInt('3', 2) ,2 进制中只能出现 0 和 1,所以 3 无法解析,结果也是 NaN 。
如何避免陷阱
如果我们想要将数组中的字符串元素转换为整数,可以使用箭头函数来明确传递参数:
console.log(['1','2','3'].map(num => parseInt(num)));
// 输出 [1, 2, 3]
总结
通过这个例子,我们可以看到,在 JavaScript 中,看似简单的方法组合使用,可能会产生意想不到的结果。在面试和实际开发中,我们需要对这些细节有足够的了解,才能避免掉入陷阱。希望本文能帮助大家更好地理解 map 方法和 parseInt 函数的使用。