2013-03-04 47 views
5

Tôi đã đọc Secrets of the JavaScript Ninja và tôi thấy mã này trong đó sản xuất một chức năng quá tải:JavaScript và chức năng quá tải làm rõ

function addMethod(object, name, fn) 
{ 
     var old = object[name]; 
     object[name] = function() 
     { 
       if(fn.length == arguments.length) return fn.apply(this, arguments) 
       else if(typeof old == 'function') return old.apply(this, arguments); 
     }; 
} 

function Ninjas() 
{ 
     var ninjas = ["Dean Edwards", "Sam Stephenson", "Alex Russell"]; 
     // addMethod is defined in Listing 2-28 
     addMethod(this, "find", function() 
     { 
       return ninjas; 
     }); 
     addMethod(this, "find", function (name) 
     { 
       var ret = []; 
       for(var i = 0; i < ninjas.length; i++) 
       if(ninjas[i].indexOf(name) == 0) ret.push(ninjas[i]); 
       return ret; 
     }); 
     addMethod(this, "find", function (first, last) 
     { 
       var ret = []; 
       for(var i = 0; i < ninjas.length; i++) 
       if(ninjas[i] == (first + " " + last)) ret.push(ninjas[i]); 
       return ret; 
     }); 
} 

var ninjas = new Ninjas(); 


assert(ninjas.find().length == 3, "Finds all ninjas"); 
assert(ninjas.find("Sam").length == 1, "Finds ninjas by first name"); 
assert(ninjas.find("Dean", "Edwards").length == 1, "Finds ninjas by first and last name"); 
assert(ninjas.find("Alex", "X", "Russell") == null, "Does nothing"); 

function assert(a,b) 
{ 
    if (a==true) console.log(b) ; else console("----"); 
} 

Theo như tôi hiểu, các addMethod luôn mang theo các giá trị old của hàm (thông qua việc đóng cửa) .

Vì vậy, cuối cùng, có một chức năng mà kiểm tra một điều kiện, và nếu nó không thành công, nó viện dẫn old chức năng mà lần lượt làm điều tương tự.

Tuy nhiên tôi không hiểu đánh giá của arguments.length (Tôi biết sự khác biệt giữa function().lengthargument.length).

Hình chữ nhật nào arguments tham chiếu đến?

enter image description here

tôi theo dõi nó trong trình gỡ lỗi, và tôi bị nhầm lẫn bởi vì lúc đầu, các thanh ghi chức năng (để arguments.length là 3 [(object, name, fn)], nhưng sau đó nó được gọi như vậy bây giờ có những lập luận khác.

thế nào là làm việc đối số

JSBin

+0

Các [MDN tài liệu trên 'arguments'] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments) có thể hỗ trợ. –

Trả lời

5

Nhưng không đề cập đến: (Mà hình chữ nhật?)

The 2nd - object[name] = function()

arguments sẽ luôn luôn tham khảo các đối tượng cho nội nhất function khai/biểu. arguments của bất kỳ bên ngoàifunction s, chẳng hạn như addMethod(object, name, fn), sẽ bị che khuất và không thể truy cập được vì tất cả đều sử dụng cùng một số nhận dạng.


Nó so sánh số lượng các đối số đã được đặt tên (fn.length) với số lượng đối số được truyền vào (arguments.length), sử dụng trận đấu 1st. Vì vậy mà:

ninjas.find()      // (0 == 0), uses `function()` 
ninjas.find("Sam")     // (1 == 1), uses `function (name)` 
ninjas.find("Dean", "Edwards")  // (2 == 2), uses `function (first, last)` 
ninjas.find("Alex", "X", "Russell") // (? == 3), no match, returns `undefined` 
+0

+1 Có thể đáng nhắc đến ở lần đầu tiên ('ninja.find()'), xem hàm ** overload ** và sau đó kích hoạt chức năng ** overload ** và khi nó vẫn không tìm thấy nó, nó đi một lần nữa .... và một lần nữa ... –

+0

@RoyiNamir Vâng, nó không kích hoạt "* quá tải *" trực tiếp cho đến khi nó có một trận đấu. Nó chỉ gọi hàm ẩn danh được tạo trong 'addMethod'. Điều này đóng vai trò như một loại vòng lặp danh sách liên kết của các tham chiếu 'cũ', leo xuống một" lỗ thỏ * "của các bao đóng cho đến khi nó tìm thấy một kết quả khớp hoặc chạm đáy. –

+0

'this' trong' fn.apply (this' tham chiếu đến 'object' trong' object [name] = {..} 'phải không? –

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