2013-03-04 88 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