我正在过滤一个数组,并在这里找到一个正则表达式.我试图理解这个:
filterArray.filter(/./.test.bind(new RegExp(key, 'g')))
Run Code Online (Sandbox Code Playgroud)
但是我不明白数组如何测试它对正则表达式的价值,或者为什么你必须从/./开始而不是只写正则表达式.在这种情况下绑定是如何工作的?
编辑:键只是一个我要匹配的字符串,"嗨"或"狗"或"任何真的".
小智 15
该.bind()
方法将返回一个函数,其中包含您传递的任何内容,作为第一个参数绑定的值this
.
既然你打电话.bind()
的.test()
,你得到的.test()
与方法this
绑定到new RegExp(key, 'g')
.
这/./
与此无关.这只是获得该RegExp.prototype.test
方法的简短方法.
结果是你将有效地做:
var regexp = new RegExp(key, 'g');
filterArray.filter(function(val) {
return regexp.test(val);
});
Run Code Online (Sandbox Code Playgroud)
您应该注意这有点危险,因为带有g
修饰符的正则表达式对象是有状态的.这意味着它总是开始一个新的搜索,前一个搜索停止.
鉴于这种过滤方案,g
似乎根本不需要,并且实际上只会导致问题.
以下是使用g
此处的危险示例:
var re = /./.test.bind(new RegExp("foo", 'g'));
var str = "foobar";
console.log(re(str)); // true
console.log(re(str)); // false
Run Code Online (Sandbox Code Playgroud)
因此,在同一个字符串上调用相同的正则表达式会产生两个不同的结果.如果我们再次召集它,它将true
再一次.
因此,考虑到作为一个.filter()
回调,让我们说key
是"foo"
,那么可以说一个val
是"foobar"
.它将被允许通过过滤器.
但是,让我们说下一个val
是"foobaz"
.搜索将在第四个字符上重新开始,而不是从第一个字符开始,因此"foo"
将无法找到.
以下是显示实际问题的具体示例:
演示: http : //jsfiddle.net/s9PzL/
var filterArray = [
"foobar",
"foobaz",
"foobuz",
"foobix"
];
var result = filterArray.filter(/./.test.bind(new RegExp("foo", 'g')));
Run Code Online (Sandbox Code Playgroud)
所有的字符串都有"foo"
,所以他们都应该通过.但结果表明不会发生.
document.body.textContent = result.join(", "); // foobar, foobuz
Run Code Online (Sandbox Code Playgroud)
我认为这样做的原因是因为你想对数组中的每个项执行测试方法.只是将测试方法传递给过滤器(可能)会搞乱方法的绑定.
这就是你的例子中的原因:
/./
Run Code Online (Sandbox Code Playgroud)
生成一个空的正则表达式
/./.test
Run Code Online (Sandbox Code Playgroud)
是该正则表达式的测试方法
/./.test.bind(new Regex(..))
Run Code Online (Sandbox Code Playgroud)
结合该方法所要求的方法,并返回执行的新方法test
,其中this
基于您提供的正则表达式key
.
它似乎可以写得更清楚:
RegExp.prototype.test.bind(new RegExp(key, 'g'))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9550 次 |
最近记录: |