2013-03-04 91 views
5

我正在讀Secrets of the JavaScript Ninja和我看到這個代碼產生一個函數過載:JavaScript和功能超負荷澄清

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("----"); 
} 

據我明白了,addMethod始終保持功能的old值(通過閉合) 。

因此,最後,還有一個功能它檢查的條件,如果失敗,它會調用old函數又做同樣的事情

但是我不明白的arguments.length評價(我知道function().lengthargument.length之間的差異)。

要其矩形不arguments指什麼?

enter image description here

我跟蹤它的調試器,而且我感到困惑,因爲在第一,功能寄存器(所以arguments.length是3 [(object, name, fn)],但後來它被調用所以現在有另一個論據。

這是怎麼工作

JSBin

+0

[開'arguments' MDN文檔(https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments)可能的援助。 – 2013-03-04 07:10:51

回答

5

但確實參數指的是? (其矩形?)

的第二 - object[name] = function()

arguments將始終指的是對象的最內function聲明/表達。任何function S的arguments,如addMethod(object, name, fn),將被遮蔽的和不可訪問,因爲它們都使用相同的標識符。


它比較的參數進行命名的(​​)數的(arguments.length)傳遞的參數的數量,使用第一比賽。因此:

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這可能是值得一提的是,在第一時間('ninja.find()'),看到** 3 **過載功能,然後激活** 2 **過載功能,當它仍然犯規找到它,它又來了....又一次... – 2013-03-04 07:12:59

+0

@RoyiNamir那麼,它不激活「*重載*」直接磨出了比賽。它只調用'addMethod'中創建的匿名函數。這充當了一種「舊」引用的鏈表循環,爬下關閉的「*兔子洞*」,直到它找到匹配或達到底部。 – 2013-03-04 07:19:00

+0

該'this'在'fn.apply(this' referes到'object'在'對象[名稱] = {..}'正確? – 2013-03-04 07:22:30