5

我正在阅读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指的是哪个矩形?

在此处输入图像描述

我在调试器中跟踪它,我很困惑,因为起初,函数寄存器(arguments.length也是 3 [(object, name, fn)],但后来它被调用,所以现在还有另一个参数。

那是如何工作的?

JSBin

4

1 回答 1

5

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

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

arguments将始终引用最里面的function声明/表达式的对象。arguments任何外部 s的function,例如addMethod(object, name, fn),都将被遮蔽并呈现为不可访问,因为它们都使用相同的标识符。


它使用第一个匹配项将命名为 ( fn.length) 的参数数量与传入 ( ) 的参数数量进行比较。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`
于 2013-03-04T07:08:26.550 回答