Để hiểu điều gì đang xảy ra, người ta phải có cái nhìn rất gần về những gì thực sự được thực hiện.
Function.prototype.method = function(name, f) {
this.prototype[name] = f;
return this;
}
Phần này khá rõ ràng, đó là "lối tắt" để mở rộng Nguyên mẫu của bất kỳ đối tượng nào.
Phép thuật xảy ra ở phần thứ hai của mã của bạn, hàm được xác định trước đó được cung cấp với chức năng tự thực thi làm tham số thứ hai!
String.method('de', function() {
var entity = {
lt : '<',
gt : '>'
};
return function() {
return this.replace(/&([^&;]+);/g, function(a, b) {
// "this" will refer to the object the function is bound to.
document.write("<br> a=" + a + " b=" + b);
var r = entity[b];
return typeof r === 'string' ? r : a;
});
};
}()); <-- The magic happens here!
Điều này có nghĩa, người phiên dịch JavaScript sẽ sử dụng giá trị trả về của hàm "đầu tiên bên trong" (một trong những cung cấp trực tiếp đến String.method
) như chức năng thực tế, kể từ khi chức năng "đầu tiên bên trong" được thực hiện trước khi gán cho nó đến số String.prototype
.
Mã bên dưới thực hiện tương tự nhưng đặt thêm một biến (de
) vào phạm vi địa phương. Cách tiếp cận ở trên không gây ô nhiễm phạm vi, đó là một cách thanh lịch hơn để đạt được điều này. Bạn thậm chí có thể unwrap nó thêm đặt entity
trong phạm vi địa phương.
var de = function() {
var entity = {
lt : '<',
gt : '>'
};
return function() {
return this.replace(/&([^&;]+);/g, function(a, b) {
// "this" will refer to the object the function is bound to.
document.write("<br> a=" + a + " b=" + b);
var r = entity[b];
return typeof r === 'string' ? r : a;
});
};
};
String.method('de', de());
Bây giờ, bạn có câu hỏi về cách a
và b
phát huy! Điều này liên quan đến cách String.replace
hoạt động khi tham số thứ hai được truyền là một hàm. Bộ định tuyến link được cung cấp trong các bình luận giải thích điều này khá tốt! Tham số a
là toàn bộ chuỗi con phù hợp, b
là "dấu ngoặc đơn được kết hợp đầu tiên" phù hợp.
[Tài liệu cho 'String.replace'] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter) phải trả lời câu hỏi đó. – DCoder
Đây là lt và gt? – Darek
Dễ hiểu điều gì xảy ra nếu bạn phát hiện ra chức năng tự thực hiện nhanh, nếu không nó sẽ đưa bạn vài phút tự hỏi tại sao 'String.de' sẽ không in mã của hàm trả về. – clentfort