5

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関数の値を保持します(クロージャーを介して)。

最後に、 条件をチェックする1 つの関数があり、それが失敗した場合は、同じことを行うold関数を呼び出します。

ただし、 の評価がわかりません(とarguments.lengthの違いは知っています)。function().lengthargument.length

はどの四角形をarguments指していますか?

ここに画像の説明を入力

デバッガーで追跡しましたが、最初は関数が登録されているため、混乱しています( arguments.length3[(object, name, fn)]ですが、後で呼び出されるため、別の引数があります。

それはどのように機能していますか?

JSビン

4

1 に答える 1

5

しかし、引数は : (どの四角形?) を参照しますか?

第2回――object[name] = function ()

arguments最も内側のfunction宣言/式のオブジェクトを常に参照します。などの外側の の は、すべて同じarguments識別子を使用するため、シャドウされてアクセスできなくなります。 functionaddMethod(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 に答える