JS深入理解—探索parseInt函数

mac2022-06-30  73

前言

看到这样一道题目: ['1','2','3'].map(parseInt) 执行结果是什么?为什么?

执行结果是:

[1, NaN, NaN]

我们将题目的代码转换一下:

['1','2','3'].map((item,index)=>{ return parseInt(item,index); })

相当于:

parseInt('1', 0); // 1 why?? parseInt('2', 1); // NaN why?? parseInt('3', 2); // NaN why??

带着思考我们来扩展下 parseInt 的知识点。

parseInt 函数

parseInt(str[,radix]) 能够将一个字符串数值转换为 radix 进制的整数。【See MDN】

参数: str

如 str 不是字符串,则先将其转为字符串,通过 ToString 抽象操作进行转换,字符串开头的空格将会被忽略。

参数: radix

radix 取值范围是 2~36,默认是 10,建议使用的时候明确指定。

返回值

返回解析后的结果,如果被解析参数的第一个字符无法被转换成数值类型,则返回 NaN。radix(例如n) 参数会把 str 当作是这个数的 n 进制表示,返回结果是10进制。

例如:

parseInt('023',8) //将 '023'看作是8进制数,返回10进制数:0x8^2+2x8^1+3x8^0 = 19

边界示例

示例一:

parseInt('1',0) // 1 parseInt('012') // 12 似乎和以下的规则3有矛盾,这里暂时不知道原因,当然不建议这么写 parseInt('0x12') // 18

当 radix 为0或者没有设置时,parseInt会根据 str 来判断基数。

以"1~9"数值开头,则会解析为10进制的整数;以"0x"数值开头,则会把其余部分解析为16进制的整数。以"0"数值开头,则会把其余部分解析为8进制或者16进制(这里存在风险,可能会出错,建议明确指定基数)

示例二:

parseInt('2',1) //NaN 其中1不在2~36范围内 parseInt('3',2) //NaN 除'1','0'外,其他均不能用来表达二进制数

示例三:

parseInt('0xF',16) //15 F 用10进制表示是15 parseInt('F',16) //15

示例四:

parseInt('17', 8) //15 1x8^1+7x8^0 = 15 parseInt(021, 8) //15 021是非字符串,首先通过ToString转换成 '17',再转换成10进制。

示例五:

parseInt(0.00000000000434, 10) //4 非常小的数,会忽略掉前面的0,保留剩下的第一个数值 parseInt(0.00000100000434, 10) //0 parseInt(0.00000010000434, 10) //1 小数点7位之后会认为是非常小的数 parseInt(4.7 * 1e22, 10) // 4 非常大的数,忽略第一位之后的

严格的解析函数

我们可以看到 parseInt 有时候的转换不如预期,规则也很多,因此在实际的开发过程中需要更加严格的校验。可以使用lodash的parseInt或者封装一个(摘抄自MDN):

// 通过正则来严格匹配 let filterInt = function (value) { if(/^(\-|\+)?([0-9]+|Infinity)$/.test(value)) return Number(value); return NaN; } console.log(filterInt('421')); // 421 console.log(filterInt('-421')); // -421 console.log(filterInt('+421')); // 421 console.log(filterInt('Infinity')); // Infinity console.log(filterInt('421e+0')); // NaN console.log(filterInt('421hop')); // NaN console.log(filterInt('hop1.61803398875')); // NaN console.log(filterInt('1.61803398875')); // NaN
最新回复(0)