高频网红面试题['1','2','3'].map(parseInt) 原理解析

9,641 阅读2分钟

1、console.log(['1','2','3'].map(parseInt));

权威原文参考 A JavaScript Optional Argument Hazard

  • 答案:[1,NaN,NaN]

  • 解析:这个题,答主我是知道答案的,因为这个题是 网红题 要解析他 我们先来看看

map这个方法他或回调函数的参数 ,和他的使用

//这是MDN
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]
  • 语法
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
 // Return element for new_array }[, 
thisArg])
  • 参数

  • callback

生成新数组元素的函数,使用三个参数:

  • currentValue

    callback 数组中正在处理的当前元素。

  • **index可选 ** 看到这里先注意起来这个参数,思考一下

    callback 数组中正在处理的当前元素的索引。

  • array可选

    callback map 方法被调用的数组。

thisArg可选

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

  • map 也是常有用的一个array的prototype方法,大家并不陌生,好现在我们来看一看 parseInt,这个方法

他们会擦出什么火花

原因

  • 注意到上面这2个家伙,接下来就好解释了
  • 原因: 其实就是 mapcallback的第二个参数 index 也就是当前元素的索引 被当做parseInt 的第二个参数radix 的来使用了

仔细想一下,我们原本以为我们的的三次调用时这样的

parseInt('1')
parseInt('2')
parseInt('3')

实际上是这样被调用的

parseInt('1',0,theArray);
parseInt('2',1,theArray);
parseInt('3',2,theArray);

好,那么重点来了,index 是如何影响 radix的呢?

  • 第一次,当我我们第一次调用的时候 是这样的:parseInt('1',0) 这个是没问题的 转十进制的 看我红框的图片

    • 返回 1
  • 第二次,调用第二个index参数是1,也是说1作为数值的基础。规范里说的很清楚了,如果基础是非0或者小于2,函数都不会查询字符串直接返回NaN。

  • 第三次,2作为基数。这就意味着字符串将被解析成字节数,也就是仅仅包含数值0和1。parseInt的规范第十一步指出,它仅尝试分析第一个字符的左侧,这个字符还不是要求基数的有效数字。这个字符串的第一个字符是“3”,它并不是基础基数2的一个有效数字。所以这个子字符串将被解析为空。第十二步说了:如果子字符串被解析成空了,函数将返回为NaN。

    • 所以这里的结果就应该是[1,NaN,NaN].

解决

这里问题所在就是容易忽视parseInt是需要两个参数的。map中有三个参数。所以这里结合起来,就导致了上面问题。 换个方式写:

['1','2','3'].map(function(value){
        return parseInt(value)
})

这样就不会出错。

当然,我们也可以写:

['1','2','3'].map(Number)


到此告一段落,后面会持续更新