['1', '2', '3'].map(parseInt)输出什么

9,100 阅读6分钟

前言

parseInt(string, radix) :用于解析一个字符串并返回指定基数的十进制整数。 parseInt(string, radix): 将一个字符串 string 转换为 radix 进制的整数, radix 为介于2-36之间的数。最后都是以十进制形式返回。

parseInt规则

  • 将一个字符串 string 转换为 radix 进制的整数, radix 为介于2-36之间的数。最后都是以十进制形式返回。
  • 函数将其第一个参数转换为一个字符串,对该字符串进行解析,然后返回一个整数或 NaN
  • 如果radix没有指定或者是0,则会被指定为10进制来解析
  • 如果string0x 0X开头,则指定为16进制来解析。
  • 第一个字符不能转换为数字,parseInt 会返回 NaN

1、string 参数如果不是字符串

MDNparseInt 语法的解释: parseInt 方法接收两个参数待解析值 string,基数 radixstring 参数如果不是字符串,则会调用其 toString 方法转换为字符串。因此遇到非字符串解析值,parseInt 内部会有两部操作:

Step1: 调用 toString 方法

(0.5).toString(); //  '0.5'
(0.05).toString(); //  '0.05'
(0.005).toString(); //  '0.005'
(0.0005).toString(); //  '0.0005'
(0.00005).toString(); //  '0.00005'
(0.000005).toString(); //  '0.000005'
(0.0000005).toString(); //  '5e-7'

注意上面的输出,我们可以发现当数字过小时,toString 输出的结果是科学计数法形式。

Step2: 截断操作

引用一段来自 StackOverflow 的解释:
parseInt 只能将字符串的前导部分解释为整数值;它忽略任何不能被解释为整数的代码单元,并且不会有忽略指示。

因此答案只会返回 5 ,其余的 e-7 被忽略。

注意事项:

如果将要解析的值放入字符串中,那么上面这种惊喜就不会出现了:

parseInt("0.0000005"); // 0
parseInt("0.000000005"); // 0

2、radix 值为 undefined、0 或未指定的

radix 值为 undefined、0 或未指定的,那 JavaScript 会如何处理这种情况:

  • 如果输入的 string0x0X 开头,那么 radix 会被假定为 16 ,字符串的其他部分按照十六进制来解析。
  • 如果输入的 string0 开头,ES5 规定使用十进制,但并非所有的浏览器都支持,因此使用 parseInt 时,需要指定 radix
  • 如果输入的 string 以其他任何值开头,radix 值为 10
parseInt("0x16"); // 22
parseInt("0888"); // 888
parseInt("123px"); // 123

3、radix 值小于 2 或 大于 36

radix 参数的值为 2 ~ 36,当 radix 小于 2 或 大于 36(不包含 0),返回值为 NaN

parseInt("123px", 1); // NaN
parseInt("123px", 38); // NaN
parseInt("123px", -1); // NaN

4、待转换字符串中,所有的可转换数字都不小于 radix 值

返回值为 NaN

parseInt("3456", 2); // NaN
parseInt("45px", 3); // NaN

5、string必须小于第二个参数radix吗?

parseInt的第一个参数string的的实数必须小于进制数?

image.png

  • 前两个解析正常,为什么第三个parseInt('125', 5)输出为7,这就不符合上面的计算公式,后来发现它自动把最后的5给删除了,输出的其实是parseInt('12', 5),这样输出就是等于7
  • 为什么第四个输出是NaN,因为参数string5开头,不符合进制所属数,所以直接返回NaN
  • 最后一个直接把55删除了,最终解析成parseInt('1', 5),输出1

结论:

  • 如果第一个参数string的第一个值就大于等于第二个参数radix,那么直接返回NaN
  • 如果第一个参数string的第一个值符合条件,其他值不符合条件,那么不符合条件的值到最后会被忽略,然后进行计算

6、parseInt 允许前导和后置空格

parseInt 允许前导和后置空格,在进行转换前,会首先删除字符串的前导和后置空格。

// 允许前导和后置空格
parseInt("  123 "); // 123

// 中间出现的空格会被当做截断符
parseInt("123 456 "); // 123

7、parseInt 可以理解正负号

parseInt("+123"); // 123
parseInt("-123"); // -123
// 只能理解第一个正负号,第二个非数字字符,因此返回 NaN
parseInt("+-123"); // NaN

运算

parseInt('123',5)

注意:此处千万不要把1*5^2 + 2*5^1 + 3*5^0直接复制下来在控制台运算,不然计算出来的跟实际parseInt('123', 5)算出来的结果不一样,至于为什么,因为^是位运算符,其实在这表达的意思是几次方的意思,正确写法:1*Math.pow(5, 2) + 2*Math.pow(5, 1) + 3*Math.pow(5, 0)

题目一:['1', '2', '3'].map(parseInt)

先看看其他例子:

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

所以,['1', '2', '3'].map(parseInt)完整写法是:

['1', '2', '3'].map((v, i, arr) => parseInt(v, i))

map():里面是个回调函数,三个参数:分别是当前值(v),下标(i),原始数组(arr)

执行顺序:['1', '2', '3'].map((v, i, arr) => parseInt(v, i)),依次输出:

  • parseInt('1', 0),radix为0,按十进制解析,所以输出 1
  • parseInt('2', 1),radix是2-36之间,没有1,所以输出 NaN
  • parseInt('3', 2),radix是2,则第一个参数只能是0,1,所以输出 NaN

扩展:

image.png

  • 数组'3',...'9'之间对应的下标值就是2~8,第一个参数都大于进制,所以都是NaN

题目二:['10', '10', '10', '10'].map(parseInt)

['10', '10', '10', '10'].map(parseInt)完整写法是:

['10', '10', '10', '10'].map((v, i, arr) => parseInt(v, i))

依次输出:

  • parseInt('10', 0),radix为0,按十进制解析,所以输出 10
  • parseInt('10', 1),radix是2-36之间,没有1,所以输出 NaN
  • parseInt('10', 2),radix是2,输出1*Math.pow(2, 1) + 0*Math.pow(2, 0),所有输出2
  • parseInt('10', 3),radix是3,输出1*Math.pow(3, 1) + 0*Math.pow(3, 0),所有输出3

题目三:parseInt(0.0000005)

parseInt (0.0000005) === 5true吗?答案是肯定的。

题目四: ['1', '7', '11'].map(parseInt)

首先,parseInt 接受两个参数,因此第三个参数会被忽略。

第一次执行, parseInt('1', 0) 会输出 1 ,因为 0 会转换成 false,而 false 会使它执行默认的进制 10 ,就是 parseInt 默认都是转换十进制;

第二次执行,parseInt('7', 1) 因为没有所谓的 1 进制,所以无法转换,输出 NaN

第三次执行parseInt('11', 2) 答案为 3 ,因为以 2 为进制转换,3 的二进制是 11。

所以最终的输出的结果就是 [1, NaN, 3]


文章摘录: