Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript and function overload clarification

Tags:

javascript

I was reading Secrets of the JavaScript Ninja and I saw this code which produces a function overload:

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

As far as I understand, the addMethod always keeps the old value of the function (via closure).

So finally, there is one function which checks a condition, and if it fails, it invokes the old function which in turn does the same thing.

However I don't understand the evaluation of arguments.length (I know the differences between function().length and argument.length).

To which rectangle does arguments refer to?

enter image description here

I tracked it in debugger, and I'm getting confused because at first, the function registers (so arguments.length is 3 [(object, name, fn)], but later it is invoked so now there are another arguments.

How is that working?

JSBin

like image 323
Royi Namir Avatar asked Mar 04 '13 06:03

Royi Namir


People also ask

Why function overloading is not possible in JavaScript?

There is no real function overloading in JavaScript since it allows to pass any number of parameters of any type. You have to check inside the function how many arguments have been passed and what type they are.

Does JavaScript allow function overloading?

Unlike the other programming languages, JavaScript Does not support Function Overloading.

How function overloading is different in JS write a JS program to perform function overloading?

In programming, function overloading refers to the concept where multiple functions with the same names can have different implementations. However, in JavaScript, if there are multiple functions with the same name, the function that is defined at the last gets executed.

What happens when you overload a function?

Using the function overloading concept, we can develop more than one function with the same name, but the arguments passed should be of different types. Function overloading executes the program faster. Function overloading is used for code reusability and to save memory.


1 Answers

But does arguments refers to : (which rectangle ?)

The 2nd -- object[name] = function ()

arguments will always refer to the object for the inner-most function declaration/expression. The arguments of any outer functions, such as addMethod(object, name, fn), will be shadowed and rendered inaccessible since they all use the same identifier.


It's comparing the number of arguments that were named (fn.length) to the the number of arguments passed in (arguments.length), using the 1st match. So that:

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`
like image 60
Jonathan Lonowski Avatar answered Sep 24 '22 21:09

Jonathan Lonowski