rob cherny.com

About

My name is Rob Cherny and I'm a professional Web Developer with 16 years of experience creating Web sites and Web-based applications. This site is where I write about my work, and random other things...

Learn More

Loading...

Close Tab

Web Development

JavaScript Function Arguments: Default Values, Passing Objects, and Overloading

This isn't all that new, but there's some clarity and refinements to be made to other references on the subject. Essentially, there's many cases where you might want to have a single JavaScript function which behaves differently based on what is passed to it.

These include 1-n scaling of arguments, default values for arguments, or even custom callbacks (a variation on function overloading). This can be extended even further by passing in objects.

JavaScript Arguments 101

Starting with the obvious, what is a JavaScript function argument? It's simply a value which can be passed into a JavaScript function to allow manipulation of that value. Meaning, you can set up a JavaScript function, pass a value to it and it will return a different thing or perform an operation based on that passed information.

Example:

  1. var myAdding = function(a,b) {
  2.         return 1 + a + b;
  3. };
  4. var x = myAdding(1,2);
  5. alert(x); // 4 (1 + 1 + 2)
  6.  
  7. var z = myAdding(2,2);
  8. alert(z); // 5 (1 + 2 + 2)

Here you've got a function where you always start with a base of 1, and need to add two values to it every time. You can yield a different amount by passing in two different values each time.

Obviously, that's the most basic example which most all people know.

JavaScript Arguments and the Length Property

The oldest example floating around in texts and the Internets is the "arguments" object which is an array-like object which is respresentative of the arguments passed into a JavaScript Function.

Example:

  1. var argCount = function(a) {
  2.         alert(arguments[0]);
  3.         alert(arguments[1]);
  4.         // bad example, but you could do it!
  5.         return true;
  6. }
  7. argCount(1,2); // browser alerts 1, then 2

There's an obvious problem with this because how do you know or count on how many items are passed in?

  1. argCount(1); // alerts 1, then undefined

The "undefined" problem we can deal with later. However to start to deal with this, this special "arguments" object is not an array, but it does have a "length" property which is easy to exploit.

  1. var argCount = function(a) {
  2.    alert("arguments length: " + arguments.length);
  3.    // what is the length?
  4.    for (var x = 0; x < arguments.length; x++) {
  5.       alert(arguments[x]);
  6.    };
  7. };
  8.  
  9. argCount(1,2,3);
  10. // browser alerts length of 3,
  11. // then value 1, then 2, then 3
  12. argCount(1);
  13. // browser alerts length of 1,
  14. // then value 1

So, you can then get sort of complicated if you want to. Say you set up your function so that every other item was a value with a different meaning? Evens and odds? Or the even the first value was a constant and every other argument meant something else?

Example:

  1. var myAdding = function(a){
  2.    var values = 0;
  3.    for (var x = 1; x < arguments.length; x++) {
  4.       values += arguments[x];
  5.    };
  6.    alert(a + values);
  7.    // recall "+" will string concatenate
  8. };
  9.  
  10. myAdding("total values: ", 1, 2);
  11. // browser alerts 3
  12. myAdding("total menu items: ", 2, 2, 2);
  13. // browser alerts 6

Here we've changed our myAdding() function to start with a message about what we're adding, set each time, and then we're looping through the remaining arguments to add them all together. Obviously not the strongest example but it illustrates the point.

More information on the arguments object can be found at this JavaScript reference.

JavaScript Default Argument Values or Optional Arguments with typeof

In many other programming languages, and indeed in the proposed JavaScript 2.0, you can define a default value for a function argument if it is not provided.

More and more online there's been other examples of this floating around, but some are more effective than others. A common one floated has been a simple or ("||") statement against the argument in question.

  1. // not the best example
  2. var functionTest = function(argu) {
  3.         argu = argu || 'my argument';
  4.         return argu;
  5. };
  6.  
  7. alert(functionTest('test'));
  8. // browser alerts "test"
  9. alert(functionTest());
  10. // browser alerts "my argument"

Here we have an example of effectively setting a default value for a function argument using 'my argument' as the value.

But what about these scenarios:

  1. alert(functionTest(null));
  2. // browser alerts "my argument"
  3. alert(functionTest(''));
  4. // browser alerts "my argument"

That's not quite literally what was passed, was it? This shows the "or" ("||") test is not correct in every case. What's better?

Nothing's perfect but you can test using the "typeof" operator to see if something being passed is not defined, or "undefined".

Example:

  1. // good example
  2. var functionTest = function(argu) {
  3.    argu = (typeof argu == 'undefined') ?
  4.      'my argument' : argu;
  5.    return argu;
  6. };
  7.  
  8. alert(functionTest('test'));
  9. // browser alerts "test"
  10. alert(functionTest());
  11. // browser alerts "my argument"
  12. alert(functionTest(null));
  13. // browser alerts null
  14. alert("'" + functionTest('') + "'");
  15. // browser alerts ''

Here we have the browser returning all the actual values passed in and also getting the default value as desired. This shows the 'undefined' test is the valid test for an optional or missing argument.

Passing JavaScript Objects as Arguments

One new technique you're seeing more and more these days involves the passage of a JavaScript object structure into a function as an argument.

I'm a big fan of this technique for several reasons:

  • provides notes in a self-documenting way what what each argument is
  • allows for flexibility in what order they are in
  • also provides flexibility on optional arguments
  • allows passing of objects in any valid JavaScript object syntax

I like to use the Object Literal syntax. Basically it works like this:

  1. var myAdding = function(o) {
  2.    return o.one + o.two + o.three;
  3. };
  4.  
  5. alert(myAdding({one:1,two:2,three:3}));
  6. //browser alerts 6
  7.  
  8. alert(myAdding({
  9.    two:4,
  10.    three:4,
  11.    one:4
  12. }));
  13. //browser alerts 12

Now, you can extend that by adding in optional arguments:

  1. var myAdding = function(o) {
  2.    o.one = (typeof o.one == 'undefined') ? 0 : o.one;
  3.    o.two = (typeof o.two == 'undefined') ? 0 : o.two;
  4.    o.three = (typeof o.three == 'undefined') ? 0
  5.       : o.three;
  6.    return o.one + o.two + o.three;
  7. };
  8.  
  9. alert(myAdding({
  10.    two:2,
  11.    three:3
  12. }));
  13. //browser alerts 5
  14.  
  15. alert(myAdding({
  16.    two:4,
  17.    one:4
  18. }));
  19. //browser alerts 8

So there's some significant power in that, and it can be quite legible as well because you know what each parameter passed in is.

Function Overloading or Custom Callbacks

Some languages such as C# allow you to define multiple functions which do different things based upon the number or type of arguments passed to them. Based upon what is passed to the function, it will call the correct function and behave differently. You can already do something similar with optional arguments as has been demonstrated. You can also expand on this by passing into a function to a custom function. This is very useful when you want your code to be extensible and portable.

  1. var myAddingPlus = function(o,call) {
  2.    o.one = (typeof o.one == 'undefined') ? 0 : o.one;
  3.    o.two = (typeof o.two == 'undefined') ? 0 : o.two;
  4.    o.three = (typeof o.three == 'undefined') ?
  5.        0 : o.three;
  6.    var z = o.one + o.two + o.three;
  7.    call = (typeof call == 'undefined') ?
  8.        function(x){return x;} : call;
  9.    return call(z);
  10. };
  11. // example 1:
  12. alert(myAddingPlus({
  13.    one: 1,
  14.    two: 4
  15.    },
  16.    function(a){
  17.       return a + 10;
  18.    }
  19. ));
  20. // browser alerts 15
  21. // example 2:
  22. alert(myAddingPlus({
  23.    one: 1,
  24.    two: 4
  25.    },
  26.    function(a){
  27.       return a * 10;
  28.    }
  29. ));
  30. // browser alerts 50
  31. // example 3:
  32. alert(myAddingPlus({
  33.    one: 1,
  34.    two: 4
  35.    }
  36. ));
  37. // browser alerts 5

In the first example, we've passed in a function which adds 10 to the values added from the passed object o. In the second example, we've passed in a function which multiplies by 10. In the last example, we do nothing, and using a default value setting in the function we've simply returned the original calculation of 1+4.

Conclusion

In this article we've covered many different and extensible ways of working with functions and function arguments. These sorts of techniques can make your code much more flexible project to project, as well as help reduce recoding multiple functions when you need to do the same things with subtle and small differences.

We looked at:

  • function argument object and length property
  • setting default and optional values for function arguments
  • passing objects into functions as arguments
  • creating custom callbacks or a form of function overloading

Jan 7, 06:39 PM in Web Development (filed under JavaScript)

  1. mahesh    Aug 10, 03:34 PM    #

    Amazing article

  2. Santi    Sep 2, 02:22 PM    #

    Great article, very well explained and written, thanks!

commenting closed for this article

In This Section