为什么原生JS FILTER函数会改变它的输出
Why does the native JS FILTER function vary its output
我使用本机JS FILTER函数有以下情况:
var array = ['hello', 'you', 'hello', 'you', 'hello', 'you', 'hello', 'you', 'hello', 'you', 'hello', 'you', 'hello', 'you', 'hello'];
var regex = new RegExp( "hello", "gi" );
function allMatches( item, index, array ){
return this.test( item );
}
现在像这样运行…
array.filter( allMatches, regex ).length;
=> 7 // should be 8.
注意:传入allMatches函数的所有8项都返回true,但是数组缺少一个项。
现在让我们按照下面的描述更正allMatches函数。
var array = ['hello', 'you', 'hello', 'you', 'hello', 'you', 'hello', 'you', 'hello', 'you', 'hello', 'you', 'hello', 'you', 'hello'];
// NO LONGER USE THIS var regex = new RegExp( "hello", "gi" );
function allMatches( item, index, array ){
return /hello/gi.test( item );
}
现在像以前一样运行…
array.filter( allMatches ).length;
=> 8 // as it should be.
请注意所有示例中的以下项目…
- 每次迭代THIS是正则表达式,因为它应该是。
- 每个应该为TRUE的迭代都为TRUE,这意味着所有8个
- THIS始终是正确的正则表达式。
我不是在寻找如何使这项工作,因为我知道一种方法来做到这一点。我想知道为什么会发生这种情况,这样我就可以避免在未来的问题。
下面是使用以下函数
的更多尝试var regex = new RegExp( "hello", "gi" ); // as before
function allMatches( item, index, array ){
return this.test( item );
}
array.filter( allMatches, regex ).length;
=> 7 // again, NOT correct.
array.filter( allMatches, /hello/gi ).length;
=> 8 // correct. Passing a regex litteral.
array.filter( allMatches, new RegExp( "hello", "gi" )).length;
=> 8 // correct. Passing the same regexp from
这里是相同的不工作的例子,但有一个引用的regex文字。var nonConstructorRegex =/hello;
array.filter( allMatches, nonConstructorRegex ).length;
=> 7 // NOT correct.
注意:我认为它与传递给regex的引用有关,但是使用引用的regex文字可以工作,而从构造函数构建的新RegExp变量则不行。请看上面的第一条。
当结果不正确时,它将第一个HELLO计数为false,它应该是TRUE。
当regex值作为引用传入时可能会发生。当regex(无论是构造的还是文字的)传入时,不需要引用。
会不会只是时间问题??
从答案中学习了MDN参考后,我明白了为什么。
的例子查找连续匹配
如果您的正则表达式使用"g"标志,您可以多次使用exec()方法来查找同一字符串中的连续匹配。当您这样做时,搜索从正则表达式的lastIndex属性指定的str的子字符串开始(test()也将推进lastIndex属性)。例如,假设您有以下脚本:
var myRe = /ab*/g;
var str = 'abbcdefabh';
var myArray;
while ((myArray = myRe.exec(str)) !== null) {
var msg = 'Found ' + myArray[0] + '. ';
msg += 'Next match starts at ' + myRe.lastIndex;
console.log(msg);
}
如何用我的例子测试这个想法…
var array = ['hello', 'hello', 'hello', 'hello'];
var regex = new RegExp( "hello", "gi" );
function allMatches( item, index, array ){
console.log(this.lastIndex)
return this.test( item );
}
array.filter( allMatches, regex ).length;
=> 2.
每次迭代将console.log。lastindex的累计位置。
因此,第一项将导致。lastindex 5作为字符串"hello"的第5个位置。
下一个hello会命中,但是. lastindex将位于位置5。.test()函数将检查字符串是否与正则表达式匹配,但在5位置。这将导致0,从而将. lastindex重置为0。
第三次迭代将从0开始,并检查hello是否匹配正则表达式,
第4次迭代将到达,但. lastindex将再次设置在5位置,因此我们将继续执行此操作,直到数组结束,在本例中为
。因此…
是 MUSTARD上校,在衣帽间,挂着"g"旗!!
这与.filter()
没有太大关系。
当你在正则表达式中包含"g"标志时,那么每次调用.test()
将执行源字符串的搜索,如果找到匹配,它将设置RegExp对象上的.lastIndex
属性的值为源字符串的索引,下一个搜索应该从哪里开始。
当您在过滤器函数中使用正则表达式字面量时,这无关紧要,因为对该函数的每次调用都会创建一个新的RegExp实例。但是,当您在连续调用中重用正则表达式时,.lastIndex
的值将产生影响。
你张贴的样本,与字符串交替匹配和不匹配的数组,不会显示任何明显的问题。然而,如果您在一行中有两个"hello"
字符串,那么它会,因为在匹配第一个字符串之后,.lastIndex
的值将是5,所以当.test()
被调用用于下一个字符串时,搜索将从字符串的末尾开始并失败。
底线:去掉"g"标志
- 动态地改变“”的URL;添加新项目”;链接使用javascript/jquery
- 在JavaScript中输出转义字符
- 如何在jQuery中将函数的输出分配给变量
- Javascript,输出结果后页面不断刷新
- jQuery:当屏幕大小改变时,如何更改默认图像和悬停图像
- Datetime格式为Friendly Time.Moment JS输出错误
- 如何将angularjs中的javascript字符串输出为循环数组
- HTML5FileReader输出到D3.js图表
- console.log以外的Javascript输出函数
- Eloquent JavaScript递归示例如何终止为返回1,但仍然输出指数值
- 输入到输出不会改变结果中的单词
- 在 HTML 文件中放置脚本标记是否会改变输出
- 前缀零改变数字加法中的输出
- 为什么将变量的console.log()移动到第二个AJAX调用中会改变输出?
- js:创建一个多选择组件.选项组件状态的组合流不输出改变的状态
- 根据下拉改变数据输出
- 为什么原生JS FILTER函数会改变它的输出
- 我如何改变我的脚本输出ul而不是选择选项
- 将复杂对象从父对象传递给子对象.任何让父节点检测其输出何时改变的方法
- 改变MVC 5上的JSON输出