map 与 parseInt 执行结果

分析 ["1", "2", "3"].map(parseInt) 的输出

问题

["1", "2", "3"].map(parseInt) 的执行结果是什么?

解答

答案是 [1, NaN, NaN]

原因分析

map 的回调函数接收三个参数:

array.map((currentValue, index, array) => {})

parseInt 接收两个参数:

parseInt(string, radix) // radix 是进制,范围 2-36

map(parseInt) 执行时,parseInt 会接收到 map 传递的前两个参数:元素值和索引。

实际执行过程

["1", "2", "3"].map(parseInt)

// 等价于
["1", "2", "3"].map((item, index) => parseInt(item, index))

// 展开后
parseInt("1", 0)  // radix 为 0,按 10 进制解析 -> 1
parseInt("2", 1)  // radix 为 1,无效进制 -> NaN
parseInt("3", 2)  // radix 为 2(二进制),但 "3" 不是有效的二进制数 -> NaN

// 结果
[1, NaN, NaN]

parseInt 的 radix 规则

// radix 为 0 或未提供:按 10 进制解析(特殊情况:0x 开头按 16 进制)
parseInt("1", 0)   // 1

// radix 为 1:无效,返回 NaN
parseInt("2", 1)   // NaN

// radix 为 2:二进制,只接受 0 和 1
parseInt("3", 2)   // NaN,因为 "3" 不是有效的二进制字符
parseInt("10", 2)  // 2

// radix 为 16:十六进制
parseInt("ff", 16) // 255

正确写法

如果想得到 [1, 2, 3],应该这样写:

["1", "2", "3"].map(Number)
// 或
["1", "2", "3"].map(item => parseInt(item, 10))
// 或
["1", "2", "3"].map(item => +item)

关键点

  • map 回调接收三个参数:(value, index, array)
  • parseInt 第二个参数是进制(radix),范围 2-36
  • parseInt("2", 1) 返回 NaN,因为不存在 1 进制
  • parseInt("3", 2) 返回 NaN,因为二进制只有 0 和 1
  • 使用 Number 或显式指定进制可避免此问题