JavaScript和函数重载澄清

时间:2013-03-04 06:55:07

标签: javascript

我正在阅读Secrets of the JavaScript Ninja,我看到这个代码产生了一个函数重载:

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)],但后来它被调用,所以现在还有另一个参数。 / p>

这是怎么回事?

JSBin

1 个答案:

答案 0 :(得分:5)

  

但是参数是指:(哪个矩形?)

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

arguments将始终引用最内层function声明/表达式的对象。任何外部 arguments的{​​{1}},例如function,都会被遮蔽并且无法访问,因为它们都使用相同的标识符。


它使用第一个匹配将命名的参数数量(addMethod(object, name, fn))与传入的参数数量(fn.length)进行比较。那样:

arguments.length