今日一题‘1 2 3’.replace(/\d/g, parseInt)

94 阅读2分钟

题目:'1 2 3'.replace(/\d/g,parseInt)

答案:'1 NaN 3'

一次面试题中看到的题目,记录一下:

replace语法:

replace([RegExp|String],[String|Function])

本质 :对str使用RegExp做match()匹配,如果匹配到多项结果(比如使用了全局匹配g,或者分组),那么每一个匹配结果都将执行一次Function函数,并且用该函数的返回值替代源字符串中的匹配项。

parseInt语法:

parseInt(string, radix)

参数描述
string必需。要被解析的字符串。如果string不是字符串,它底层将通过使用 ToString 抽象操作 将其转成字符串
radix可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。

到这里,我们就知道这两个语法的用法了。

题目核心关键点就是:parseInt函数的两个参数到底接受的是replace匹配后的哪两个数呢

这里我做了一个打印

QQ图片20230419132734.png 我们可以看到,输出了3次Arguments,因为我们使用全局匹配g后,会match到3个项,所以就执行了3次function。
['1',0,'1 2 3'] 分别是 [ 匹配到的第一个值,该值的索引,原数据 ]

所以可以推到parseInt收到的参数分别是

'1 2 3'.replace(/\d/g,function(val,index){
    console.log(val,index);
});
//1 0
//2 2
//3 4

//如下:
'1 2 3'.replace(/\d/g, (val,index)=>parseInt(val,index))
parseInt(1,0)   //  1  
parseInt(2,2)   //  NaN
parseInt(3,4)   //  3

不了解parseInt的可能会奇怪为什么parseInt(1,0)返回1。这就涉及到parseInt(string, radix)的第二个参数radix的一些规则了。

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

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

所以

    parseInt(1,0) //radix为0,那么string就会解析为10进制,相当于 parseInt(1,10)  => 1
    parseInt(2,2) //radix为2介于2~36之间,好像没什么问题,但是string除'1','0'外,其他均不能用来表达二进制数!!!因此等于NaN
    parseInt(3,4) //3*4^0 => 3*1 => 3

到此,这个题目就分析完了。
题目看起来好像很简单,但是考察的东西还蛮多蛮细的。又学到了以前没注意到的细节知识点了。一起加油吧!