javascript 添加函数脚本 - 有人可以解释一下吗?

javascript add function script - can someone explain?

我在示例中查找这段代码,它应该按名称在对象上创建函数。 据我了解,它还可以在对象上创建相同功能的重载。

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

所以如果创建一个新对象像

var ninja = {};

而不是添加如下函数:

addMethod(ninja,'whatever',function(){ /* do something */ });
addMethod(ninja,'whatever',function(a){ /* do something else */ });
addMethod(ninja,'whatever',function(a,b){ /* yet something else */ });

该对象应包含 3 个 whatever 函数的重载。

我不明白addMethod函数的问题:

我了解到我们将最后一个函数存储在旧版本中。 我们以这种方式创建闭包吗?使用匿名函数?

so 执行这行代码:

 else if (typeof old == 'function')
            return old.apply(this, arguments);

它将递归调用之前定义的所有函数直到匹配?

谁能解释一下?

谢谢

好的,我会试着用例子来解释,想象一下:

var obj = {
  foo: function() {}
};

var foo2 = function(arg) {};

调用 addMethod(obj, 'foo', foo2) 将用创建的匿名函数替换 obj.foo。是的,那是一个闭包,在它里面 fn 将永远是 foo2.

下次调用 obj.foo 时将调用匿名函数。在闭包 fn(等于 foo2)中,length 等于 foo2 期望接收的参数数量,arguments.length 等于实际收到的参数数量

obj.foo(1);

在这种情况下,fn.lengtharguments.length 都是 1,然后 foo2 将使用我发送的参数进行调用。

obj.foo();

在这种情况下 fn.length 是 1 但 arguments.length 是 0 闭包将检查是否有一个 old 函数并调用它传递参数(在这种情况下没有)。

如果您使用新函数再次调用 addMethod,它将递归查找,直到找到接收相同数量的已发送参数的函数或直到它到达最后一个函数。

var foo3 = function(arg1, arg2) {};
addMethod(obj, 'foo', foo3);

obj.foo(1, 2); // will trigger foo3
obj.foo(1); // will trigger foo2
obj.foo(); // will trigger the original foo

添加一个具有相同数量参数的函数将使旧函数不再被调用。

var foo4 = function(arg) {};
addMethod(obj, 'foo', foo4);

obj.foo(1); // will trigger foo4

doesn't args.arguments are the 3 always?

不,arguments.length 表达式最直接位于 内部 函数表达式 object[name] = function(){ ... } 的内部,而不是 addMethod。因此,arguments 指的是传递给 object[name] 上定义的函数(即新定义的函数)的参数。

but don't understand what we store with the new anonymous function

代码的重点是根据传递的参数数量调用不同版本的函数。

如果您不在某处存储旧版本的函数,那么将无法调用它。

why we testing fn.lenth into arguments length (doesn't args.arguments are the 3 always? of (addMethod))

一个函数的length属性是预期个参数的个数。即创建它的函数声明或函数表达式的 () 之间的标识符数。

arguments 对象的 length 属性 是实际传递给它的参数的数量。

看这个例子:

function myFunction(foo, bar) {
  document.body.appendChild(
    document.createElement("br")
  );
  document.body.appendChild(
    document.createTextNode(
      "The function was called with " + arguments.length + " arguments"
    )
  );
}


document.body.appendChild(
  document.createTextNode(
    "The length of the function is " + myFunction.length
  )
);

myFunction();
myFunction("a", "b", "c", "d", "e");