JavaScript only pretends to support function overloading

I frequently use method overloading a lot in my C# code to allow optional parameters, so when I wanted to implement a simple popup function with optional support for virtual root and website based on the url, here's what I came up with:

function showPopUp(virtual, url, height, width)
{
 
if(location.pathname.indexOf(virtual)>=0)
 { 
  
//we're running in the virtual root, so prepend it to the url
  
url=virtual+url;
 }
 showPopUp(url, height, width);
}

function showPopUp(url, height, width)
{
 window.open(url, 
'PopUpWindow''toolbar=no,directories=no,menubar=no,resizable=no,status=no,height=' + height + ',width=' + width);
}

Javascript sneakily pretends to support this - no script error - every time I called the function, the virtual root wasn't being added on. That's because Javascript doesn't support method overloading; it just uses the function which was defined last (thanks, Bertrand, for verifying my hunch). I had to give the second function a different name, and it all worked.

Here's an easy way to verify - this will show the second message:

<html>
<
head>
<
script>
function test(one,two)
{
alert('expected: first function with two parameters');
}

function test(one)
{
alert('surprise! second function with one parameter');
}
</script>
<
/head>
<
body onload="javascript:test('first','second')">
<
/body>

 

Published Sunday, October 02, 2005 12:10 AM by Jon Galloway

Comments

# re: JavaScript only pretends to support function overloading

If you had only the first version, you could still call test(5), and the "two" variable would just be undefined, which you can test for.

Saturday, October 01, 2005 11:00 PM by tyler burd

# re: JavaScript only pretends to support function overloading

Good point, Tyler. That's a better pattern.

However, there are two issues here:
1) Method overloading requires different strategies in Javascript. Your approach solves that.
2) Programmers who are used to the overloading syntax of other languages (me, for example) are likely to run into trouble when they try this in Javascript. It's especially tricky because there's no compile error, just different behavior than expected.

Saturday, October 01, 2005 11:48 PM by Jon Galloway

# re: JavaScript only pretends to support function overloading

Yeah, that's because you can pass any number of parameters to a javascript function and access them via the arguments collection. Javascript doesn't have a good method resolution strategy. It only takes the last one.

function x()
{
alert(arguments[0]);
alert(arguments[1]);
}

x(1,2);

Saturday, October 01, 2005 11:57 PM by Haacked

# re: JavaScript only pretends to support function overloading

You could use named arguments with the only parameter an object. Then just check for the existence of the named argument. You can even pass a function as an argument.

<html>
<head>
<script language=javascript>
function test(argTest)
{
'x' in argTest ? alert('x = ' + argTest.x) : alert('x does not exist');
'y' in argTest ? alert('y = ' + argTest.y) : alert('y does not exist');
'z' in argTest ? alert('z = ' + argTest.z) : alert('z does not exist');
}

function functest()
{
return 'this is from a function';
}

</script>
</head>
<body>
<button onclick="test({x:1, y:'two'});">Test x,y</button><br>
<button onclick="var zarg='z arg'; test({z:zarg});">Test z</button><br>
<button onclick="var f = functest(); test({x:f});">Test function</button><br>
</body>
</html>

Sunday, October 02, 2005 10:14 PM by Bill

# re: JavaScript only pretends to support function overloading

To pretend we can do overloading in javascript further, you can overload with parameters with different types using typeof and other tricks.

I sometimes have functions that take a string or array as an argument. The function might look like this:

function doStuff(arg1) {
if (/string/.test(typeof(arg1))) {
// do the string
} else {
// do the array
}
}

Note that if you use typeof(array), you will end up with "object" as returned value. That's why you need other tricks, such as determine the object has a property called "length".

Sunday, October 02, 2005 11:44 PM by frogcoder

# re: JavaScript only pretends to support function overloading

Hi there,

I have developed a javascript library (not published yet) where you can inject code at the beginning or end of an existing function. You could utilize it to be able to really overload a function by inserting an (if arguments[0] instanceof String && arguments[1] instanceof Number ...) to execute only the code that should be run when certain parameters are passed. I will implement this so that you can do something like : myMethod.overloads(String, Number, Object, CustomClass, code);

Wednesday, October 19, 2005 2:50 PM by Hermann Klinke

# Information &raquo; Sorting Javascript Arrays (of Objects)

Wednesday, January 17, 2007 11:54 PM by Information » Sorting Javascript Arrays (of Objects)

# re: JavaScript only pretends to support function overloading

Still i think it is possible

Thursday, June 05, 2008 7:29 AM by Satish

# re: JavaScript only pretends to support function overloading

Just to point out responding to frogcoder - you should not test for an array by looking for a length property. After all, String objects (not to be confused with string literals) also have a type of Object and a length property.

You can test for Array with a simple conditional:

if (arg1 instanceof Array)

{

 // Do something

}

Similarly, you should test for a string like this:

if (typeof(arg1) == "string" || (arg1 instanceof String))

{

 // Do something

}

This handles both string literals ("string") and String objects (new String("string")), which are interchangeable.

Friday, August 01, 2008 10:00 AM by Daniel

Leave a Comment

(required) 
(required) 
(optional)
(required)