JavaScript only pretends to support function overloading - Jon Galloway

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 2, 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 1, 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 1, 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 1, 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 2, 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 2, 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

# re: JavaScript only pretends to support function overloading

Still i think it is possible

Thursday, June 5, 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 1, 2008 10:00 AM by Daniel

# re: JavaScript only pretends to support function overloading

Really interestnig and informative!!:)

Tuesday, June 2, 2009 7:13 AM by kiruthikka

# re: JavaScript only pretends to support function overloading

Umm... JavaScript doesn't pretend to support function overloading, it simply doesn't support it at all. I guess that the reason why you can respecify a function is solely due to the nature of the language: in browser side scripting, all attempts are often made to execute the code and thus such decisions are required to consolidate for common user errors. Besides, the ability to repurpose a function name is by itself a nice feature ;D

And yes, I know I'm replying to a 5-year-old post :D

Tuesday, August 4, 2009 12:30 AM by Ice

# re: JavaScript only pretends to support function overloading

In fact, im suprised that someone as a Microsoft Most Valueable Professional posts this on a asp.net forums, clearly showing a complete lack of understanding what they are actually doing.

Monday, February 8, 2010 7:36 AM by Arjen

# re: JavaScript only pretends to support function overloading

@Arjen - Did you notice the date on this post? It's 5 years old. I've learned a lot in the past 5 years, as I hope we all have.

Wednesday, February 10, 2010 5:40 PM by Jon Galloway

# re: JavaScript only pretends to support function overloading

5 years old or not, it's still on the internet today, read by people who seek answers to their questions and maybe end up reading pages like this after using a search engine.

The point I'm trying to make is that you should not make posts based on your own false assumptions, presenting it as the truth. Especially as an MVP. Because this way, you're not helping the community.

If you know stuff, share it, if you don't, get to the bottom of it.

Wednesday, March 3, 2010 3:23 AM by Arjen

# re: JavaScript only pretends to support function overloading

Arjen:

No knowledge is absolute. All we can ever do is pretent to understand something..

Jon:

Thanks for sharing it IS helpful (even if it is 5 years old)..

Sunday, March 21, 2010 4:09 AM by O Ehn

# re: JavaScript only pretends to support function overloading

Some good info on here =) I have a lot of build functions that take about 20 arguments so I finally decided to try and find a better way to set defaults and then only adjust what was necessary.  Below is the basics of what I will be using and might be of some practical use to anybody else in the same situation.  Essentially its a function that sets its defaults and then evals on the arguments array to change any of the presets.

function f_start()

{

x();

x(['vName','Cow']);

x(['vWidth',90],['vHeight',200],['vName','Cow']);

}

function x()

{

var vWidth = 60;

var vHeight = 80;

var vName = 'Box';

for(var i=0;i<arguments.length;i++)

{

eval(arguments[i][0] + ' = "' + arguments[i][1] + '";');

}

alert('Making a '+vName+' that is '+vWidth+' wide and '+vHeight+' high');

}

//Making a Box that is 60 wide and 80 high

//Making a Cow that is 60 wide and 80 high

//Making a Cow that is 90 wide and 200 high

Thursday, March 25, 2010 2:45 PM by Chad

# re: JavaScript only pretends to support function overloading

yes you 100% right i have tested same.

Wednesday, January 19, 2011 3:23 AM by Khalil

# re: JavaScript only pretends to support function overloading

A better way to handle sending 20 arguments to your function is to create a class with 20 properties.  Then pass the newly instantiated object with your 20 properties/values to the method.

function ThisMethodNeeds20Arguments(myNewObject)

function NewClass() {

 this.property1

 ..

 this.property20

}

var instanceOfNewClass = new NewClass();

instanceOfNewClass.property1 = "whatever";

instanceOfNewClass.property2 = "more...";

instanceOfNewClass.property3 = 3;

instanceOfNewClass.property4 = false;

..

instanceOfNewClass.property10 = { 1, 2, 3 };

Thursday, January 20, 2011 7:00 PM by Flak

# re: JavaScript only pretends to support function overloading

Knowledge neve become old...

Monday, February 25, 2013 12:01 PM by Khan