记录一次使用replace函数的翻车过程。
根据用户输入的开始时间和有效期限来判断驾驶证是否,判断逻辑如下:
a(年月日) + b(年) ? (当前时间 年月日) return : false
小需求,然后风风火火的写下了如下的代码
function fn1(start, step) {
var newTime = start.replace(/(\d{4})/, Number('$1') + step)
var loseTime = new Date(newTime).getTime()
var nowTime = new Date().getTime()
console.log(newTime)
return loseTime > nowTime
}
fn1('2017-11-14', 1) // NaN-11-14
看了看代码,觉得应该是 Number('$1') 里面的$1没有取到值,js将它解析成了字符串'$1'
,就出现了NaN。
不使用Number()没有问题,打印20171-11-14
,+号也不行。算了,换个方式,再搞下。
查资料理解到replace里面的$1可以忽略RegExp,可以直接写成$1,那要是加上呢,会不会就好了?
此时,坑开始了
然后我就写下了如下的代码
function fn1(start, step) {
var newTime = start.replace(/(\d{4})/, Number(RegExp.$1) + step)
var loseTime = new Date(newTime).getTime()
var nowTime = new Date().getTime()
console.log(newTime)
return loseTime > nowTime
}
fn1('2017-11-14', 1) // 1-11-14
fn1('2017-11-14', 1) // 2018-11-14
什么鬼,让我冷静下。第一次调用难道没有获取到正则匹配到的值吗?
打断点,我瞅瞅,果然如此,第一次调用的时候RegExp.$1
是' '
,看来我得重新理解下replace这个函数了。
我的理解是匹配到的字符串赋值给了RegExp.$1
,看来并不是这样,它是表明上次匹配到的值。
知道了原因,就有改进的方法了,这里我列出3种:
1、在匹配的时候,先计算出要替换成的值
function fn2(start, step) {
let year = Number(start.split('-')[0]) + step // 看这里看这里
var newTime = start.replace(/(\d{4})/, year)
var loseTime = new Date(newTime).getTime()
var nowTime = new Date().getTime()
console.log(newTime)
return loseTime > nowTime
}
2、将replace函数的第二个值改成函数(推荐写法)
function fn3(start, step) {
var newTime = start.replace(/\d{4}/, (a,b,c)=>{
// a 匹配到的值 b匹配到值的下标 c原始字符
return Number(a) + step
})
var loseTime = new Date(newTime).getTime()
var nowTime = new Date().getTime()
console.log(newTime)
return loseTime > nowTime
}
3、先将RegExp.$1
赋值,再使用
function fn4(start, step) {
/(\d{4})/.test(start)
var newTime = start.replace(/(\d{4})/, Number(RegExp.$1) + step)
var loseTime = new Date(newTime).getTime()
var nowTime = new Date().getTime()
console.log(newTime)
return loseTime > nowTime
}
总结:
碰到replace函数要计算替换值的时候,最好直接写成函数,开始的bug我的理解是Number
函数执行的时候,正则还没有将$1
赋值,或者就不能这样写,这样写的话,replace函数就把$1
当前普通字符串来解析了。