快速理解["1", "2", "3"].map(parseInt)

这道很经典的面试题已通过去不少年了,可是如今依然被不少人 传颂 着。之前研究过这道题,以为弄懂了。可是今天被别人问起这道题时回答的又有点 模棱两可面试

咱们先看一下输出结果数组

考察点:

  1. Array.map()
  2. parseInt()
  3. 进制(进制之间转换)

那咱们分别研究一下这三个要点。浏览器

Array.map()

这个应该是咱们最经常使用的Array方法之一。早在ES6就有了。
map() 方法建立一个新数组,其结果是该数组中的每一个元素都调用一个提供的函数后返回的结果。bash

var new_array = arr.map(function callback(currentValue,index,array) {
 // Return element for new_array 
},thisArg)
复制代码
  • Array.map()参数

callback 生成新数组元素执行的函数(三个参数)
    currentValue callback 数组中正在处理的当前元素。
    index callback 数组中正在处理的当前元素的索引。
    array map 方法被调用的数组。函数

thisArg 执行 callback 函数时使用的this 值。ui

返回值 一个新数组,每一个元素都是回调函数的结果。this

  • Array.map()示例

let arr = ["1","2","3"].map(function callback(currentValue,index,array) {
    console.log(`${currentValue}+${index} [${array}]`)
    return currentValue*2
});
console.log(arr);

output:
// 1+0 [1,2,3]
// 2+1 [1,2,3]
// 3+2 [1,2,3]
// [2, 4, 6]


var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots的值为[1, 2, 3], numbers的值仍为[1, 4, 9]
复制代码

parseInt()

parseInt(string, radix);
复制代码
  • parseInt()参数

string 要被解析的值。若是参数不是一个字符串,则将其转换为字符串。
radix 一个介于2和36之间的整数(数学系统的基础),表示上述字符串的基数。当未指定基数时,不一样的实现会产生不一样的结果,一般认为其值默认为10,可是请在使用时老是显示的指定它。spa

注意 radix参数为n 将会把第一个参数看做是一个数的n进制表示,而返回的值则是十进制的。
这是MDN上的解释 parseInt(string, radix) 将一个字符串 string 转换为 radix 进制的整数, radix 为介于2-36之间的数。
对于上面两句话我理解的时候老是有点怪。我以为能够这样理解parseInt(string, radix), 把radix进制的string转成10进制的值,并返回
例如:code

parseInt('123', 5) // 将'123'看做5进制数,返回十进制数38 => 1*5^2 + 2*5^1 + 3*5^0 = 38
复制代码

这里将5进制的123转成10进制为38cdn

  • parseInt()示例

parseInt("20"); //返回20  radix默认为10,也就是10进制的20转成10进制,那么也是20
parseInt("10",2);//返回2  radix为2,也就是2进制的10转成10进制,1*2^1+1*2^0 = 2
parseInt("103",2);//返回2 radix为2,也就是2进制的103转成10进制,由于2进制只包括0,1,因此3不是2进制的数字(只计算3以前的值也就是10),1*2^1+1*2^0 = 2
parseInt("213",4);//返回39 radix为4,也就是4进制的213转成10进制,2*4^2+1*4^1+3*4^0 = 32+4+3 = 39
...
复制代码

这里进制是怎样转换的呢,好比4进制的213转成10进制

2*4^2+1*4^1+3*4^0 = 32+4+3 = 39

拿第一个数*进制的第一个数的位数的次方+第二个数*进制的第二个数的位数的次方+···直到加上最后一位数*进制的0次方(位数从右向左数0,1,2...)
复制代码

看下面的介绍:

在基数radix为 undefined,或者基数为 0 或者没有指定的状况下,JavaScript 做以下处理:

若是字符串 string 以"0x"或者"0X"开头, 则基数是16 (16进制).
若是字符串 string 以"0"开头, 基数是8(八进制)或者10(十进制),那么具体是哪一个基数由实现环境决定。ECMAScript 5 规定使用10,可是并非全部的浏览器都遵循这个规定。所以,永远都要明确给出radix参数的值。
若是字符串 string 以其它任何值开头,则基数是10 (十进制)。
若是第一个字符不能被转换成数字,parseInt返回NaN。

算术上, NaN 不是任何一个进制下的数。 你能够调用isNaN 来判断 parseInt 是否返回 NaN。NaN 参与的数学运算其结果老是 NaN。

复制代码

那咱们来看这几个例子怎么返回

parseInt("1",0); //radix为10也就是10进制的1转10进制,也就是 1
parseInt("2",1);//radix 介于2和36之间的整数,当radix不在这个范围内的解析全都返回 NaN
parseInt("3",2);// 3不是2进制的数字,3前面也没有其余数字,因此这里返回 NaN
复制代码

咱们知道parseInt为一个函数,其源代码应该是这个样子的:

function parseInt(string, radix){
    return xxx;
}
复制代码

当写成这样Arrar.map(parseInt)的形式时 callback === parseInt
parseInt(string, radix)的两个参数分别对应currentValue index
这个时候parseInt就变成了

function parseInt(currentValue,index) {
    return xxx;
};
复制代码
["1", "2", "3"].map(parseInt)
            ||
["1", "2", "3"].map(function parseInt(currentValue,index) {
    return xxx;
})
            ||
["1", "2", "3"].map(function callback(currentValue,index) {
    return parseInt(currentValue,index);
})           
复制代码

currentValue1return parseInt(1,0)
currentValue2return parseInt(2,1)
currentValue3return parseInt(3,2)

在上面咱们就分析了

parseInt("1",0);//返回 1
parseInt("2",1);//返回 NaN
parseInt("3",2);//返回 NaN
复制代码

so 综上所述:["1", "2", "3"].map(parseInt) = [1, NaN, NaN]

相关文章
相关标签/搜索