2012-10-27 38 views
5

Tôi là ví dụ về mô-đun thử nghiệm từ JavaScrit: Các phần tốt. Tôi không biết ai đi vào a và b trong hàm (a, b). Bằng cách nào đó nó hoạt động.Giá trị của hàm (a, b) là gì?

Function.prototype.method = function(name, f) { 
    this.prototype[name] = f; 
    return this; 
} 
String.method('de', function() { 
    var entity = { 
     lt : '<', 
     gt : '>' 
    }; 
    return function() { 
     return this.replace(/&([^&;]+);/g, function(a, b) { 
      document.write("<br> a=" + a + " b=" + b); 
      var r = entity[b]; 
      return typeof r === 'string' ? r : a; 
     }); 
    }; 
}()); 
document.write("<br>" + '&lt;&gt'.de()); 
+4

[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

+0

Đây là lt và gt? – Darek

+0

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

Trả lời

1

Để 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 ab 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.

+0

Vâng, đây là một câu trả lời tuyệt vời. Cảm ơn nhiều! –

+0

@ JAny Cảm ơn, bạn có phiền chấp nhận điều này như là câu trả lời không? (Nhấp vào dấu chọn màu xanh lá cây bên dưới số điểm của câu trả lời để làm như vậy.) Cũng là một câu hỏi hay, đã cho tôi một thời gian để tìm ra những gì đang xảy ra. – clentfort

Các vấn đề liên quan