匿名函数中调用array.pop()结合RegExp的异常行为咨询
问题分析:
filter回调中调用regex.pop()失效的原因 这事儿的核心其实是对pop()方法特性和filter执行逻辑的理解偏差——我来给你拆解清楚:
关键知识点:Array.pop()的破坏性
pop()是一个会直接修改原数组的方法:它会移除数组的最后一个元素并返回该元素;当数组为空时,它返回undefined。
filter的执行逻辑
filter会遍历目标数组的每一个元素,对每个元素都执行一次你传入的回调函数。这就意味着,如果你在回调里调用pop(),每次遍历都会执行一次pop(),持续修改原正则数组。
结合你的代码逐行分析
我们聚焦那个出问题的调用:arr.filter( a=> a.match(regex.pop()))
你的arr有4个元素,所以回调会执行4次:
- 第一次处理
"001":regex.pop()取出第二个正则,此时regex变为[new RegExp("01$")],"001"不匹配,返回false。 - 第二次处理
"02":regex.pop()取出仅剩的第一个正则,此时regex变成空数组,"02"不匹配,返回false。 - 第三次处理
"012":regex.pop()返回undefined,a.match(undefined)等价于匹配字符串"undefined",自然不匹配,返回false。 - 第四次处理
"12301":此时regex已经是空数组,pop()仍返回undefined,同样匹配失败,返回false。
所以最终filter返回空数组,且执行完后regex也被清空了——这就是它“无法正常工作”的根本原因。
而你其他正常的调用逻辑:
var take = regex.pop();:只执行一次pop(),把正则存到变量里,filter遍历全程用同一个正则,自然没问题。a.match(new RegExp("01$")):每次回调都创建新正则,和原数组无关,当然正常。a.match(regex[0]):你第一次pop()后,regex只剩第一个正则,直接通过索引访问不会修改原数组,所以也能正常匹配。
解决建议
如果想使用正则数组的最后一个元素过滤,又不想修改原数组,可以:
- 提前取出最后一个元素(和你第一个正常写法类似,但不破坏原数组):
var takeLastRegex = regex[regex.length - 1]; console.log(arr.filter(a => a.match(takeLastRegex))); - 或者复制原数组后再
pop(),避免修改原数组:console.log(arr.filter(a => a.match([...regex].pop())));
内容的提问来源于stack exchange,提问作者Julien Maret
相关产品推荐
相关产品推荐

