这些关于-parseInt-的题你都会吗

45次阅读

共计 2371 个字符,预计需要花费 6 分钟才能阅读完成。

下面的结果你都知道是多少吗?欢迎在评论区给出推算过程~

parseInt(6.1e23, 10)
parseInt('10', 10)
parseInt('2 10', 10)
parseInt(NaN)
parseInt(NaN, 36)
['1', '7', '11'].map(parseInt)
['1', '2', '3'].map(parseInt)
parseInt('0x1')
parseInt('0x11')

parseInt

parseInt(str[, radix:]) // 返回一个整数或者 NaN

parseInt 表示把一个参数 strradix 进制转换成 10 进制数。

明确指定 radix 将会给你省很多麻烦,同时你最好能明确知道 str 是什么样的字符串。

  • str 要被解析的值,应该是字符串类型,如果不是字符串,则按照 ToString 规则转换,str 开头和尾部的空格会被省略;
  • radix 表示的是 str 的基数,介于 2 到 36 之间的整数(包括 2、36),这个基数要特别注意

    • radix 不填 或者为 0 或者为 undefined 时,str0x 或者 0X 开头则默认 radix16str0 开头,radix 可能是 810(这个不确定,依据环境而定),如果以其他任何值开头则 radix10
    • 基数为 [2, 36] 之间的值时,以 radix 为基数进行转换;
  • 返回值:首尾空格自动省略,首个不为空格的字符不可表示则返回 NaN

    • 省略首尾空格,例如 parseInt('3 10', 10) str 有多个空格,这时候会省略首尾空格,从 3 开始,如果再遇到空格,则无法解析,直接返回 3
    • 如果 str 的第一个非空格字符无法被转化为数值类型,则返回 NaN,比如 parseInt('2', 2) parseInt('a', 10) 等第一位超过了 radix 能表示的数,所以返回 NaN;
    • 中途碰到不可转换的值则停止转换,如 parseInt('10a11', 10) str 前两位为 10,在十进制可以表示,a 不能,就会直接停止转换,返回 10

总结:

  • str 首尾空格会被省略
  • 如果 parseInt 遇到了不属于 radix 参数所指定的基数中的字符(首尾空格除外)那么该字符和其后的字符都将被忽略;
  • 在被 parseInt 转换前,最好已经明确知道 str 是字符串,radix 也不要省略,避免出现推断从而导致脱离本意;
  • radix 明确指定属于 [2, 36](包括边界)

上面的规则可能比较晦涩,下面来几组 demo。

// [parseInt('1', 0), parseInt('2', 1), parseInt('3', 2)]
//  radix 为 0,str 为 1,则转换为 parseInt(1, 10) => 1
// [1, NaN, NaN]
['1', '2', '3'].map(parseInt) => [1, NaN, NaN]

// 去除首尾空格
parseInt('10', 10) // 10
// 去收首尾空格之后,中途有空格则返回前面的数字
parseInt('3 10', 10) // 3
// 10 进制无法表示 a
parseInt('a 10', 10) // NaN

parseInt('0x1') // 1 正常,radix 16
+'0x1' // 1
Number('0x1') // 1

// 带 e 的字符串对 parseInt 可能触发错误的结果
parseInt('6.1e23', 10) // 6 异常
+'6.1e23' // 6.1e+23
Number('6.1e23') // 6.1e+23

parseInt(6.1e23, 10) // 6 异常
+6.1e23 // 6.1e+23
Number(6.1e23) // 6.1e+23

parseInt 涉及到的类型转换

str 最好是你已经知道的字符串,如果传入了数字和其他类型,那会怎么处理?来看看 ToString 内部转换的规则。

可以看到 undefinednull 被转换成了对应的字符串。

转换数字

对数字类型,第 5 条之后的非常难懂,其中包括以下数字的转换,一个数可以用科学计数法来表示,类似 s*10ew(s 在 [1, 10] 闭区间上),然后呢 w 小于等于 20 则用常规表示,如果大于 20 则用指数形式表示,如下图。

简单来说,数字的转换规则就是应用 [Number.prototype.toString ( [ radix] )](http://yanhaijing.com/es5/#426)

radix 为 [2, 36] 闭区间的值,不填则默认为 10,不能填 0,在 parseInt 这里是 10。

转换对象

对象转换为字符串涉及到 ToPrimitive 内部处理机制,下一篇文章将会详细介绍。这里给出大概转换流程。

parseInt(obj, radix) 会把 obj 对象先转换成字符串,然后按照 radix 转换为对应的结果。objobj 结果有影响的三个是 valueOftoStringSymbol.toPrimitive

var obj = {
  value: 1,
  valueOf() {console.log('valueOf')
    return 2
  },
  toString() {console.log('toString')
      return '3'
  },
  [Symbol.toPrimitive](hint){console.log(hint)
    if(hint === 'string') {return '4'}
    return 5
  }
}

parseInt(obj, 10)
// string
//  4

// 去掉 Symbol.toPrimitive 属性,再执行
// toString
// 3

由于是转换为字符串,而 toString 返回的是原始值,所以不会执行 valueOf


今天的文章就到这里,感谢阅读~

欢迎在本文下面评论发表您的见解。

欢迎大家关注我的掘金和公众号,专注于提升前端程序员的核心竞争力,不断探索【前端规范】、【框架原理】,通过分析源码告诉大家如何【参与开源项目】、提升知名度,建立个人品牌。

欢迎进群讨论~~

正文完
 0