parseInt

parseInt用法记录。

语法

1
parseInt(string, radix)

参数

  • string 要被解析的值。如果不是String类型的,会被转为String
  • radix 可选 | 取值范围:从236,代表string参数的进制。如radix: 10,代表string的内容应按照10进制解析。

返回值

要么是从string参数解析出的一个整数,要么就是NaN

规则

  • 允许string参数前后带有空格,解析时会被忽略。
  • string参数中的有效字符,从前到后依次解析。
  • 如果解析遇到的字符不能被转换为radix参数所对应进制中的有效数字,则会忽略该字符以及所有后续字符,并返回到该字符为止已解析的整数值。2进制的有效数字是0、1,10进制有效数字是0~9,16进制有效数字是0~9、A~F。
  • 超过10进制,A~Z这些字母,可用来表示数字,比如16进制里面,A~F可以用来表示10~15之间的数。
  • radix等于1,或大于36,返回值一定是NaN
  • string中的第一个非空格字符,不能被转换为radix对应进制中的有效数字,返回值一定是NaN
  • 解析可以理解正负号,但是符号只允许出现一次。
  • 非常大或非常小的数字,在字符串表示形式中,会使用e字符,所以在使用parseInt时会有意外结果。

特殊地,如果radixundefind0、未指定,则radix实际值按照如下规则判定:

  • 如果string的有效数字部分以0x0X开头,则radix会被判定为16。
  • 如果string的有效数字部分以0开头,则radix会被判定为8或10,取决于实现。ES5明确规定应该判定为10,但不是所有浏览器都遵守了这个规定。
  • 如果string的有效数字部分以其它值开头,则radix被判定为10。

举例

举例一:

1
2
3
4
5
6
7
8
9
10
11
12
//1.
parseInt('10', 37); // NaN
//2.
parseInt('.10', 10); // NaN
//3.
parseInt(',10', 10); // NaN
//4.
parseInt('2', 2); // NaN
//5.
parseInt('A', 16); // 10
//6.
parseInt("Hello", 8); // 根本就不是数值

解析:

  1. 37超出了radix36
  2. .是第一个非空格字符,不能转换为数字
  3. ,是第一个非空格字符,不能转换为数字
  4. 2不是2进制的有效数字(0,1)
  5. A是16进制中的有效数字,对应10进制的10,所以可以被成功解析
  6. 第一个字符无法转为8进制的有效数字

举例二:

1
2
3
4
5
6
// 1
parseInt(' +10', 10); //10
// 2
parseInt(' ++10', 10); //NaN
// 3
parseInt(' - 10', 10); //NaN

解析:

  1. 去掉空格后,正确地解析了符号和数字
  2. 有2个符号,第二个符号会被当成普通字符尝试解析为数字,结果失败,导致最后结果为NaN
  3. 负号后面还有一个空格,这个空格,不是位于string参数的首尾,会被当成第一个字符尝试解析为数字,结果失败,导致最后结果为NaN

举例三:以下例子均返回15

1
2
3
4
5
6
7
8
9
10
11
12
13
parseInt("0xF", 16); //将0xF当成16进制解析
parseInt("F", 16); //将F当成16进制解析
parseInt("17", 8); //将17当成8进制解析
parseInt(021, 8); //021是个8进制整数,等于10进制的整数17,然后转换为字符串"17",再继续解析,最后结果跟上面一样
parseInt("015", 10);//"015"开头的字符串,0被忽略,直接当成10进制数字解析
parseInt(15.99, 10);//"15.99"中的.不是一个有效数字,所以解析到它为止
parseInt("15,123", 10);//,不是一个有效数字,所以解析到它为止
parseInt("FXX123", 16);//第一个x不是16进制的有效数字,所以解析到它为止
parseInt("1111", 2);//1111的二进制数,转换为10进制就是15
parseInt("15 * 3", 10);//15后面空格不是有效数字,所以解析到它为止
parseInt("15e2", 10);//15后面的e不是有效数字,所以解析到它为止
parseInt("15px", 10);//15后面p不是有效数字,所以解析到它为止
parseInt("12", 13);//12按照13进制解析成10进制就是15, 12 => 1 * 13 + 2 => 15

举例四:以下例子均返回4

1
2
3
parseInt(4.7, 10);
parseInt(4.7 * 1e22, 10); // 非常大的数值变成 4
parseInt(0.00000000000434, 10); // 非常小的数值变成 4

解析:上面3个例子的第一个参数不是字符串类型,所以会被转换为字符串:

1
2
3
Number(4.7, 10) + ""; // "4.7"
Number(4.7 * 1e22, 10) + ""; // "4.7e+22"
Number(0.00000000000434, 10) + ""; // "4.34e-12"

所以说:

非常大或非常小的数字,在字符串表示形式中,会使用e字符,所以在使用parseInt时会有意外结果。

举例五

请问下面代码的执行结果:

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

正确答案是:

1
[1, NaN, NaN]

这是因为Array.prototype.map方法的签名是:

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

parseInt被传入map的第一个参数时,parseInt真正被调用时会传入三个参数,分别是元素、元素索引以及数组本身,那么['1', '2', '3'].map(parseInt)就等同于以下三个调用:

1
2
3
parseInt('1', 0) // `radix`被指定为0,ES5规定这种情况下`radix`应该被判定为10,所以最终结果是1
parseInt('2', 1) // `radix`被指定为1,结果一定是NaN
parseInt('3', 2) // `radix`被指定为2,3不是2进制的有效数字,所以结果也是NaN