0

i look for this piece of code in an example that should create functions at object by name. as i understand it also can create overload of the same function on the object.

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

so If creating a new object like

var ninja = {};

and than adding functions like:

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

the object should contain 3 overload of the whatever function.

the problem I don't understand addMethod function:

I understand that we store the last function in old. do we create a closure this way? with the anonymous function?

so for executing this line of code:

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

it will recursively call all the functions defined earlier until match?

can someone explain?

thanks

3 Answers 3

1

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

The point of the code is to call different versions of the function based on the number of arguments passed.

If you don't store the old version of the function somewhere, then there won't be any way to call it.

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

The length property of a function is the number of expected arguments. i.e. the number of identifiers between the ( and ) of the function declaration or function expression that created it.

The length property of an arguments object is the number of arguments that were actually passed to it.

See this example:

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

0

Ok, I'll try to explain with example, imagine this:

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

var foo2 = function(arg) {};

Calling addMethod(obj, 'foo', foo2) will replace obj.foo with that anonymous function created. Yes, that's a closure, inside it fn will always be foo2.

Next time you call obj.foo the anonymous function will be called. Inside the closure fn (that is equal to foo2) will have it's length equal to the numbers of parameters foo2 expects to receive and arguments.length is equal to number of arguments actually received

obj.foo(1);

In this case fn.length and arguments.length are both 1 then foo2 gets called with the argument I sent.

obj.foo();

In this case fn.length is 1 but arguments.length is 0 the closure will check if there's an old function and call it passing the arguments (in this case nothing).

If you call addMethod again with a new function it will look recursively until it finds a function that receive the same number of arguments sent or until it reaches the last function.

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

Adding a function with the same number of arguments will make the old one never be called again.

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

obj.foo(1); // will trigger foo4
2
  • I understand that we store the last function in old. do we create a closure this way? with the anonymous function? so for executing this line of code: else if (typeof old == 'function') return old.apply(this, arguments); it will recursively call all the functions defined earlier until match? can someone explain?
    – user5467599
    Commented Feb 2, 2016 at 9:48
  • Look at the edited answer, I hope I could make myself clear
    – gfpacheco
    Commented Feb 2, 2016 at 12:32
0

doesn't args.arguments are the 3 always?

No, the arguments.length expression is most immediately inside of the inner function expression object[name] = function(){ ... }, not addMethod. Thus, arguments refers to the arguments being passed into the function defined on object[name] (i.e., the newly-defined function).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.