仓库源文站点原文


title: Array.map(parseInt)为什么返回了NaN date: 2017-12-23 19:29:48 tags: JavaScript categories: Node.js

description: 简单来说,当调用['1', '2', '3'].map(parseInt)的时候,会返回什么结果?答案是[1, NaN, NaN]

为什么没有得到想要的[1, 2, 3]?先来看parseInt的文档

parseInt

parseInt(string, radix);

参数

描述

parseInt 函数将其第一个参数转换为字符串,解析它,并返回一个整数或NaN。如果不是NaN,返回的值将是作为指定基数(基数)中的数字的第一个参数的整数。

基数大于 10 时,用字母表中的字母来表示大于 9 的数字。例如十六进制中,使用 A 到 F。

一些细节(keng)

  1. 一些数中可能包含e字符(例如6.022e23),使用parseInt去截取包含e字符数值部分会造成难以预料的结果。例如:

    parseInt('6.022e23', 10); // 返回 6
    parseInt('6.022e2', 10);  // 返回 602
    
  2. 当parseInt遇到不属于radix参数所指定的基数中的字符(eg: 有人告诉你0103101是2进制),那么该字符(3)和其后的字符(101)都将被忽略,接着返回已经解析的整数部分(010)。parseInt 将截取整数部分,开头和结尾的空白符允许存在,会被忽略。那么NaN的出现情况就是,string的第一个字符(除空白)不属于radix指定进制时,因为parseInt什么都没有解析到。

    parseInt('123', 'afdsaf'); // 返回123
    
  3. 在没有指定基数,或者基数为 0 的情况下,JavaScript 作如下处理:

  4. 将整型数值以特定基数转换成它的字符串值可以使用 intValue.toString(radix);

Array.map

其实看完parseInt的文档就已经清晰了,再来看map

const new_array = arr.map(function callback(currentValue[, index[, array]]) {
    // Return element for new_array
}[, thisArg])

参数

通常情况下,callback 只需要接受一个参数,就是正在被遍历的数组元素本身。但这并不意味着 map 只给 callback 传了一个参数。

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

最终分析

调用['1', '2', '3'].map(console.log)观察,列举出当['1', '2', '3'].map(parseInt)的时候发生了什么。

  parseInt('1', 0, ['1', '2', '3']);
  parseInt('2', 1, ['1', '2', '3']);
  parseInt('3', 2, ['1', '2', '3']);

由于parseInt只接受了前两个参数,过滤掉array得到如下。

  parseInt('1', 0); // radix为0,按十进制输出1
  parseInt('2', 1); // radix为1,不满足2到36范围
  parseInt('3', 2); // radix为2,将3看成二进制数,但3并不是二进制,无法转换

再换一个数组,也可以按照此逻辑推算正确结果了。