[前端经典题目分析] ['1', '2', '3'].map(parseInt) what & why ?
这个题目也算是非常经典的题目了,其实真的要说难度也没什么难度,就是考察对于基本api的使用深度(我一开始真不知道parseInt的第二个参数和map回调函数的第三个参数是啥[扶额)
回归题目,如果第一眼看到这个问题脑海里最先蹦出的答案肯定是[1, 2, 3],因为看上去就是对三个字符串一次做parseInt的转换。对此的回答是:
真正的答案是[1, NaN, NaN]。让我们先看一下map函数和parseInt函数的详细使用方法:
map函数
map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
可以看到map函数的两个参数,分别是callback回调函数和thisArg。
callback 函数会被自动传入三个参数:数组元素,元素索引,原数组本身。
对于 thisArg,如果 thisArg 参数有值,则每次 callback 函数被调用的时候,this 都会指向 thisArg 参数上的这个对象。如果省略了 thisArg 参数,或者赋值为 null 或 undefined,则 this 指向全局对象 。
需要记住的是,map函数不会改变原有数组的值。
实例:
var array1 = [1, 4, 9, 16];
// pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1);
// expected output: Array [2, 8, 18, 32]
parseInt函数
parseInt() 方法用于将字符串转换为十进制数字
parseInt(string, radix);
string为要被转换的值。如果参数不是一个字符串,则将其转换为字符串(使用 ToString 抽象操作)。字符串开头的空白符将会被忽略。
radix为一个介于2和36之间的整数(数学系统的基础),表示上述字符串的基数。比如参数"10"表示使用我们通常使用的十进制数值系统。始终指定此参数可以消除阅读该代码时的困惑并且保证转换结果可预测。当未指定基数时,不同的实现会产生不同的结果,通常将值默认为10。
parseInt('123', 5) // 将'123'看作5进制数,返回十进制数38 => 1*5^2 + 2*5^1 + 3*5^0 = 38
返回值:返回解析后的整数值。 如果被解析参数的第一个字符无法被转化成数值类型,则返回 NaN。
这里主要了解parseInt第二个参数的作用即可,其他的附上MDN的详细介绍
回归题目
['1', '2', '3'].map(parseInt)
这里的实际陷阱就是map回调函数和parseInt的第二个参数,我们将上述语句写得更详细一点:
['1', '2', '3'].map((value, index) => {
parseInt(value, index);
});
那么实际运行步骤就很清晰了,分别运行了一下三步:
parseInt('1', 0) // radix为0时,且string参数不以“0x”和“0”开头时,按照10为基数处理。返回1
parseInt('2', 1) // 基数为1(1进制)表示的数中,最大值小于2,所以无法解析,返回NaN
parseInt('3', 2) // 基数为2(2进制)表示的数中,最大值小于3,所以无法解析,返回NaN
所以最后返回值为[1, NaN, NaN]
衍生
那么如果需要返回[1, 2, 3]的话怎么办呢,除了详细修改map内的回调函数,不给parseInt传radix,也可以直接使用Number():
['1', '2', '3'].map(Number)
Number() 函数把对象的值转换为数字。
如果参数是 Date 对象,Number() 返回从 1970 年 1 月 1 日至今的毫秒数。
如果对象的值无法转换为数字,那么 Number() 函数返回 NaN。
已有 2 条评论
测试一下评论系统
Reply测试一下~
Reply