Phương thức .bind()
sẽ trả về một hàm với bất kỳ thứ gì bạn đã chuyển làm đối số đầu tiên được ràng buộc làm giá trị this
.
Vì bạn đang gọi điện thoại .bind()
từ .test()
, bạn đang nhận được phương pháp .test()
với this
ràng buộc để new RegExp(key, 'g')
.
/./
không có liên quan ở đây. Nó chỉ là một cách ngắn để đến phương thức RegExp.prototype.test
.
Kết quả là bạn sẽ có hiệu quả được thực hiện:
var regexp = new RegExp(key, 'g');
filterArray.filter(function(val) {
return regexp.test(val);
});
Bạn nên lưu ý rằng đây là một chút nguy hiểm, bởi vì một đối tượng regex với modifier g
là stateful. Điều này có nghĩa là nó luôn luôn bắt đầu một tìm kiếm mới, nơi tìm kiếm trước đó.
Với trường hợp lọc này, g
dường như không cần thiết và có thể thực sự chỉ gây ra sự cố.
Dưới đây là một ví dụ về sự nguy hiểm của việc sử dụng các g
đây:
var re = /./.test.bind(new RegExp("foo", 'g'));
var str = "foobar";
console.log(re(str)); // true
console.log(re(str)); // false
Vì vậy, gọi regex như nhau trên cùng một chuỗi sản xuất hai kết quả khác nhau. Nếu chúng tôi gọi lại lần nữa, nó sẽ là true
một lần nữa.
Vì vậy, cho việc sử dụng như một callback .filter()
, chúng ta hãy nói key
là "foo"
, sau đó cho phép nói một val
là "foobar"
. Nó sẽ được cho phép thông qua bộ lọc.
Nhưng giả sử val
tiếp theo là "foobaz"
. Tìm kiếm sẽ tiếp tục trên ký tự thứ tư thay vì bắt đầu từ ký tự thứ nhất, do đó, không thể tìm thấy "foo"
.
Dưới đây là ví dụ cụ thể cho thấy các vấn đề trong hành động:
DEMO:http://jsfiddle.net/s9PzL/
var filterArray = [
"foobar",
"foobaz",
"foobuz",
"foobix"
];
var result = filterArray.filter(/./.test.bind(new RegExp("foo", 'g')));
Tất cả các chuỗi có "foo"
, vì vậy tất cả họ sẽ nhận được thông qua. Nhưng kết quả cho thấy điều đó không xảy ra.
document.body.textContent = result.join(", "); // foobar, foobuz
Nếu bạn cung cấp cho chúng tôi biến 'key' sau đó có. –
@DavidStarkey Vui lòng xem chỉnh sửa của tôi. – ptf
Xem https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind –