2

In John Resig tutorial on Javascript, there's a code used for function overloading, which I couldn't figure out how it works :

function addMethod(object, name, fn){
  // Save a reference to the old method
  var old = object[ name ];

  // Overwrite the method with our new one
  object[ name ] = function(){
    // Check the number of incoming arguments,
    // compared to our overloaded function
    if ( fn.length == arguments.length )
      // If there was a match, run the function
      return fn.apply( this, arguments );

    // Otherwise, fallback to the old method
    else if ( typeof old === "function" )
      return old.apply( this, arguments );
  };
}

function Ninjas(){
  var ninjas = [ "Dean Edwards", "Sam Stephenson", "Alex Russell" ];
  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;
  });
}
  1. Why the second addMethod doesn't over write the first one ?
  2. Why do we need to keep a reference to old ?

1 Answer 1

3

Both of your questions answer one another. The second addMethod does overwrite the first find with a closure, that thanks to the old object containing the first find, is able to fall back to it in case the 2nd find mismatches the argument count.

When the third call to addMethod is done, it's basically doing the same thing, recursively. So it overwrites the closure with another closure, where old is the object of which the function find is a closure with the 2nd find and the old old object containing the 1st find. Phew.

Here's an approximate graphic representation:

find -> [ find3  ]
        [ old2 --]--> [ find2  ]
                      [ old1 --]--> [ find1 ]
                                    [ null  ]
Sign up to request clarification or add additional context in comments.

1 Comment

But after the third addMethod is called , we have this.find pointing to a function , which inside of it , fn expects 2 parameters in the argument , and old expects 1 parameter in the argument. What happens to the case where there's no argument. How is that handled ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.