2011-01-28 25 views
11

Giả sử bạn có hai chức năng có chữ ký sau đây:Làm cách nào để phát hiện một hàm JavaScript có chữ ký nào đó đã được đăng ký?

  1. addClass(class)
  2. addClass(class, duration)

Những sống trong một thư viện của bên thứ ba (không có giải thưởng cho đoán mà !!).

Nếu bạn gọi addClass() với hai tham số nhưng chỉ có chữ ký 1 được đăng ký, sẽ không có lỗi và chữ ký 1 sẽ được gọi. Tham số thứ hai bị bỏ qua.

Vì vậy, có cách nào để phát hiện chữ ký 2 có hai tham số đã được đăng ký không?

+4

Bạn biết rằng nếu bạn có thể gọi phiên bản một đối số với hai đối số, nó sẽ đơn giản bỏ qua đối số thứ hai, tôi đoán? – lonesomeday

Trả lời

25

Bạn có thể sử dụng thuộc tính length của đối tượng hàm để kiểm tra chữ ký. Ví dụ:

function x(a) {} 
function y(a,b) {} 

alert(x.length); // shows "1" 
alert(y.length); // shows "2" 
8

Không có quá tải phương thức gốc trong JavaScript. Bạn có thể tạo riêng của bạn, mặc dù: http://ejohn.org/blog/javascript-method-overloading/

(Update 11/5/15: Các liên kết có vẻ là đã chết, đây là Google Cache version)

Vì vậy, nếu bạn làm

function addClass(class) { console.log('1 arg'); }; 
function addClass(class, duration) { console.log('2 args'); }; 

thứ hai ghi đè đầu tiên. Vì vậy, ngay cả khi bạn gọi "addClass (1)", đầu ra vẫn sẽ là "2 args". Giống như đang thực hiện

someObject.addClass = function(a) {...} 
someObject.addClass = function(a, b) {...} 

Phiên bản "đầu tiên" sẽ bị mất.

+0

+1 cho [link] (http://ejohn.org/blog/javascript-method-overloading/) – jwaliszko

+0

liên kết đã chết – Alex

+0

@Alex Cảm ơn, tôi đã thêm liên kết bộ nhớ cache của google –

3

Nó không phải là rất khó khăn để đạt được, nhưng phương pháp của Resig là không nhiều, vì nó chỉ kiểm tra chiều dài đối số, mà chỉ liên quan liên quan đến chữ ký cuộc gọi thực.

Phương pháp Johannes thực sự là phương pháp ghi đè không nhiều chữ ký cuộc gọi, và dù sao cũng sẽ thất bại trong chế độ JS Strict, nơi nhiều lệnh khai báo cùng tên bị cấm.

Để thực hiện đúng cách, bạn sẽ cần phải thực hiện nó thông qua chuyển tiếp cuộc gọi, gói mỗi chữ ký cuộc gọi trong một tấm séc loại/tồn tại:

function myFunction(arg1, arg2, arg3){ 
    switch(true){ 
    case arg1 instanceof someObject: 
     myFunction_signature1.apply(this, arguments); 
     break; 
    case typeof arg1 === "string": 
     myFunction_signature2.apply(this, arguments); 
     break; 
    } 
} 

Nó trở nên phức tạp hơn một chút khi một số params là không bắt buộc là tốt.

0

Nếu bạn đang sử dụng nút, bạn có thể sử dụng func.toString() và phân tích cú pháp kết quả để nhận chữ ký đang được sử dụng.

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