['1', '2', '3'].map(parseInt) 输出什么?为什么?

输出: [1, NaN, NaN]

为什么:

1.map 函数和 parseInt 函数说明:

Array.prototype.map()说明,参考 mdn

1
var arr = [];
2
var new_array = arr.map(function callback(currentValue, index, array) {
3
  // Return element for new_array
4
});

map 函数接受一个callback生成新数组元素的函数

callback 函数会被自动传入三个参数:

数组元素(currentValue | 必选),

元素索引(index | 可选),

原数组本身(array | 可选)


parseInt(string, radix)说明,参考 mdn

string

要被解析的值。如果参数不是一个字符串,则将其转换为字符串(使用 ToString 抽象操作)。字符串开头的空白符将会被忽略。

radix

一个介于 2 和 36 之间的整数(数学系统的基础),表示上述字符串的基数。比如参数”10”表示使用我们通常使用的十进制数值系统。始终指定此参数可以消除阅读该代码时的困惑并且保证转换结果可预测。当未指定基数时,不同的实现会产生不同的结果,通常认为其值默认为 10,但是请在使用时总是显示的指定它。

则上面的代码就变成这样

1
["1", "2", "3"].map((item, index) => {
2
  return parseInt(item, index);
3
});

即返回的值分别为:

1
parseInt("1", 0); // 1
2
parseInt("2", 1); // NaN, 第二个参数不在2-36之间
3
parseInt("3", 2); // NaN, 3 不是二进制

2.深度解析:parseInt(string, radix)

1
// radix参数
2
// 默认为10(十进制)
3
// radix为0时,且string参数不以“0x”和“0”开头时,按照10为基数处理
4
5
// 如果第一个参数string不能被转换成数字,parseInt返回NaN。
6
7
parseInt("Hello", 2); // NaN
8
parseInt(10); // 10
9
parseInt(10, 10); // 10
10
parseInt(10, 0); // 10
11
12
// radix 取值范围为 2-36。  超过36返回NaN。 小于2不等于0即只能是1时返回NaN。为0时,且string参数不以“0x”和“0”开头时,按照10为基数处理
13
14
parseInt(10, 0); // 10
15
parseInt(10, 1); // NaN
16
parseInt(10, 3); // 3
17
parseInt(10, 37); // NaN
18
19
// 如何计算最终输出?
20
21
parseInt(10, 3);
22
// 首先参数string中, 每一位都小于3(1 < 3 && 0 < 3),并且 radix参数在2到36之间 ,所以这时候我们应该是有个正确的输出的 。
23
// 计算: 现在是3进制,则输出结果为:0 * (3^0) + 1 * (3^1) = 3 ==>输出 3
24
25
parseInt(101, 2); // 5
26
// 同理, 101每一位都小于2(1 < 2 && 0 < 2),并且 radix在2到36之间
27
// 计算: 现在是2进制,则输出结果为:1 * (2^0) + 0 * (2^1) + 1 * (2^2) = 5 ==>输出 5
28
29
parseInt(102, 2); // 2
30
// 在102中 ,第三位2 >= 2 (radix = 2) ,并且 radix在2到36之间
31
// 这个时候忽略大于等于radix位及其之后的所有数值 。则现在 102 ==> 10
32
// 计算: 现在是2进制,则输出结果为:0 * (2^0) + 1 * (2^1) = 2 ==>输出 2
33
34
parseInt(1061, 3); // 3
35
// 在1061中 ,第三位 6 >= 3 (radix = 3) ,并且 radix在2到36之间
36
// 这个时候忽略大于等于radix位及其之后的所有数值 。则现在 1061 ==> 10
37
// 计算: 现在是3进制,则输出结果为:0 * (3^0) + 1 * (3^1) = 3 ==>输出 3
38
39
parseInt(3061, 3); // NaN
40
// 第一位大于等于radix时,NaN

3.实际代码应该怎么写?

1
["1", "2", "3"].map(n => parseInt(n, 10));
2
// [1, 2, 3]

如果数组每项都是数字字符串的话,可以这样

1
["1", "2", "3"].map(Number);
2
// [1, 2, 3]

参考链接:

1.mdn Array.prototype.map

2.mdn parseInt

3.https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/4