JavaScript添加函数脚本 - 有人可以解释一下

javascript add function script - can someone explain?

本文关键字:解释 一下 函数 添加 脚本 JavaScript      更新时间:2023-09-26

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

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 函数:

我知道我们将最后一个函数存储在旧函数中。我们以这种方式创建闭包吗?使用匿名功能?

因此,要执行此行代码:

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

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

有人可以解释一下吗?

谢谢

但不明白我们使用新的匿名函数存储什么

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

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

为什么我们将 fn.lenth 测试到参数长度(args.arguments 不是总是 3 的吗?

函数的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");

好的,我将尝试用示例进行解释,想象一下:

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

args.arguments不是总是3吗?

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