Tôi có câu hỏi khá thú vị về EcmaScript-5 Function.prototype.bind implementation. Thông thường khi bạn sử dụng ràng buộc, bạn làm điều đó theo cách này:Function.prototype.bind
var myFunction = function() {
alert(this);
}.bind(123);
// will alert 123
myFunction();
Được rồi vì vậy đó là mát mẻ, nhưng những gì là giả sử xảy ra khi chúng ta làm điều này?
// rebind binded function
myFunction = myFunction.bind('foobar');
// will alert... 123!
myFunction();
Tôi hiểu rằng đó là hành vi hoàn toàn hợp lý trong điều kiện như thế nào Function.prototype.bind được thực hiện (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind). Nhưng trong điều kiện thực tế, đó là hành vi hoàn toàn vô dụng phải không? Câu hỏi đặt ra là: nó là lỗi hay tính năng? Nếu đó là lỗi, tại sao nó không được đề cập đến? Nếu đó là một tính năng, tại sao Google Chrome với bản cài đặt "liên kết" gốc hoạt động hoàn toàn theo cùng một cách?
Để làm cho nó rõ ràng hơn, những gì theo ý kiến của tôi sẽ có ý nghĩa hơn, đây là đoạn mã mà thực hiện Function.prototype.bind một chút khác nhau:
if (!Function.prototype.bind) {
Function.prototype.bind = function() {
var funcObj = this;
var original = funcObj;
var extraArgs = Array.prototype.slice.call(arguments);
var thisObj = extraArgs.shift();
var func = function() {
var thatObj = thisObj;
return original.apply(thatObj, extraArgs.concat(
Array.prototype.slice.call(
arguments, extraArgs.length
)
));
};
func.bind = function() {
var args = Array.prototype.slice.call(arguments);
return Function.prototype.bind.apply(funcObj, args);
}
return func;
};
}
Bây giờ thử điều này:
// rebind binded function
myFunction = myFunction.bind('foobar');
// will alert... "foobar"
myFunction();
Theo tôi, thay thế "này" có ý nghĩa hơn ...
Vì vậy, những gì bạn nghĩ về nó?
Đó là một tính năng. Nếu bạn có thể ghi đè lên nó, nó sẽ không thực sự "bị ràng buộc", phải không? Các chi tiết có thể được tìm thấy trong đặc điểm kỹ thuật: http://ecma262-5.com/ELS5_HTML.htm#Section_15.3.4.5 –
Chắc chắn nhưng nếu có, thì cách xác định xem hàm có bị ràng buộc với một cái gì đó? hoặc tại sao nó không ném bất kỳ ngoại lệ khi cố gắng để rebind nó? Vấn đề là nó làm cho nó vô cùng khó khăn để gỡ lỗi, nếu bạn không biết nếu chức năng đã bị ràng buộc hoặc bạn đối phó với bản sao đầu tiên của nó. Điều đó đã xảy ra với tôi ngày hôm qua, và tôi đã dành gần một ngày để tìm ra nguồn gốc của vấn đề ... – Ruslan
Dù sao thì, có vẻ như không ai trả lời câu hỏi này, vì vậy nếu có ai đó sẽ có cùng một vấn đề, tôi đã tạo một workaroud mà bạn có thể tìm thấy ở đây: http://www.angrycoding.com/2011/09/to-bind-or-not-to-bind-that-is-in.html – Ruslan