Method overloading in Javascript

To simulate method overloading in Javascript, many “if” statements are often used, which makes the code alot less intuitive.

So, I came up with the following function to simulate method overloading without harming the readability of the source code.

/**
 * You can find more about this function at
 * http://nagoon97.com/method-overloading-in-javascript/
 *
 * Copyright (c) 2008 Andy G.P. Na <[email protected]>
 * The source code is freely distributable under the terms of an MIT-style license.
 */
function methodOverloading(funcName, args) {
    var sFuncName = funcName;
    var func = null;

    sFuncName += "$" + getType(args[0]);
    for (var i = 1; i < args.length; i++) {
        sFuncName += "$" + getType(args[i]);
    }

    if (func = eval(sFuncName))
        return func.apply(this, args);

    throw (sFuncName + " is not defined");
}

Just place the function like the following and you are ready to go.

function add() {
    // pass in the function name as the 1st element of the 2nd argument
    return methodOverloading.apply(this, ["add", arguments]);
}

Now, you can overload a function just by naming the new functions with the type of parameters that the function takes, each parameters separated by a string.

function add$string$string(str1, str2) {
    return str1 + ", " + str2;
}

function add$number$number(num1, num2) {
    return num1 + num2;
}

function add$undefined() {
    return "no parameter is given!";
}

And when you call the function

alert(add("s1", "s2")); // this will display "s1, s2"
alert(add(1, 2)); // this will display 3
alert(add()); // this will display "no parameter is given!"

Please note that you need to include getType() function that I have posted HERE.
getType() is used to give methodOverloading() function the ability to overload method with user defined custom objects.
If this feature is not needed and you do not want to include the function, you can change it to typeof() and use it as

function methodOverloading(funcName, args) {
    var sFuncName = funcName;
    var func = null;

    sFuncName += "$" + typeof(args[0]);
    for (var i = 1; i < args.length; i++) {
        sFuncName += "$" + typeof(args[i]);
    }

    if (func = eval(sFuncName))
        return func.apply(this, args);

    throw (sFuncName + " is not defined");
}

And just in case you were wondering how to use this in a function,

function inc() {
    this.do = function() {
        return methodOverloading.apply(this, ["this.do", arguments]);
    }
    this.do$string = function(str) {
        return str + ", " + str;
    }
    this.do$number = function(num) {
        return num + 1;
    }
}

oInc = new inc();

alert(oInc.do("ABC"));
alert(oInc.do(1));

 

Improved typeof for the exact object type

When I first started writing scripts in Javascript, the typeof() operator did not capture much of my attention.

Because of my experience in other programming languages, I naturally believed that the operator would give me the exact name and this firm belief cost me many hours of debugging.

And when I realized that the operator won’t even tell me whether a given object is an instance of Array or Date, it was very frustrating because I’ve designed the entire script based on the assumption that the operator would provide me the exact object type.

So, I wrote the following short function, which privodes the constructor’s function name when it was given an object.

/**
 * You can find more about this function at
 * http://nagoon97.com/gettype/
 *
 * Copyright (c) 2008 Andy G.P. Na <[email protected]>
 * The source code is freely distributable under the terms of an MIT-style license.
 */
function getType(v){
 var result = typeof(v);
 if (result == "object"){
  result = "@unknown";
  if(v.constructor){
   var sConstructor = v.constructor.toString();
   var iStartIdx = sConstructor.indexOf(' ' ) + 1;
   var iLength = sConstructor.indexOf('(' ) - iStartIdx;

   var sFuncName = sConstructor.substr(iStartIdx, iLength);
   if (iStartIdx && sFuncName) result = sFuncName;
  }
 }
 return result.toLowerCase();
}

“@” was added in front of the word “unknown” because the function name can actually be “unknown” and this confusion can be avoided by adding “@”, which cannot be used for function names.