Optional Function Arguments in JavaScript
Many programming languages support optional function arguments - ie. functions in which certain arguments are optional. You can set a default value for any argument - so if the argument is not present, the default value will be used. Unfortunately, JavaScript is not one of these languages - so we will have to use a bit of trickery to get this effect in JavaScript.
In Other Languages
PHP is one of the languages that does this very well...
function myFunction($mandatory_argument,$optional_argument = 1) {
/* ...Whatever... */
}
This don't need much explaining - the first argument is mandatory - you must provide it or the script will show an error. However, the second argument is optional. If you don't provide it, it will default to 1. If you did provide an argument, it will use that value.
This is the effect we want in javascript.
JavaScript Methods for Optional Arguments
In JavaScript, this effect can be mimicked using a number of ways...
Simple method
The simplest method of doing this is to check for the argument and create a new variable with the name of the argument if said argument is not present. This can be done in the following way...
function war(enemy,reason) {
if(!enemy) { //The mandatory argument is not present - die with error(no pun intended)
alert("Please choose an enemy before starting a war");
return false;
}
if(!reason) { //If the optional argument is not there, create a new variable with that name.
var reason = "They have Nukes!";
}
/* ...Do what you want with the arguments... */
}
This method is often seen in event handler functions - as some browsers provide the event as an argument of the function while others just set the global variable 'event'.
function doSomething(e) {
if (!e) var e = window.event; //<-- see this part.
alert(e.type);
}
Unlimited Arguments
Most of the time, we provide an argument list when declaring a function. But we can avoid that and create a function that will take unlimited number of arguments. These arguments can be accessed using the 'arguments' variable. You will understand this concept much easily if you have coded in Perl. In Perl this is the only way to create a function that can accept arguments. A javascript example illustrating this method is given below.
function accident() {
for( var i = 0; i < arguments.length; i++ ) {
alert("This accident was caused by " + arguments[i]);
}
}
accident("me","a car","alcohol","a tree that had no right to be in the path of my driving");
You can assign a number to all needed arguments. If a argument is not present, use the default - like this...
function accident() {
//Mandatory Arguments
var driver = arguments[0];
var condition = arguments[1]
//Optional Arguments
var blame_on = (arguments[2]) ? arguments[2] : "Irresponsible tree" ;
}
accident("Me","Drunk");
Associative Arrays
This method gives all the optional arguments through an associative array. This method is used by a number of JavaScript Frameworks out there. Prototype, Mochikit, Dojo etc. have used this method to enable the programmer to provide more options for any function that is provided by the library. An example...
dojo.io.bind({
url: "web2_dot_oh.xml.php",
mimetype: "text/xml",
load: ajaxHandle
});
Here, the only argument is an associative array that contains all the data needed by the function. One major advantage of the function is that argument order is unnecessary. Each argument have a label to which it is associated - so the programmer will find it easier to remember. Even if they cannot remember it, they will find it the code more readable if they use this method.
This method can be used in the following way...
function person(options) {
var default_args = {
'name' : "Binny V A",
'me' : true,
'site' : "http://www.bin-co.com/",
'species': "Homo Sapien"
}
for(var index in default_args) {
if(typeof options[index] == "undefined") options[index] = default_args[index];
}
/* options[] has all the data - user provided and optional */
for(var i in options) {
alert(i + " = " + options[i]);
}
}
person({
'name' : "George W. Bush",
'me' : false,
'site' : "miserable failure"
});

Comments
and just write:
Thanks for the code samples, and the wry commentary.
Micro-optimization is kind of meh in these days of modern technology though. :P
Correction: e ||= window.event throws a syntax error.
In reality you can use
e |= window.event
Example:
x = null;
y = 32;
x |= y
>>>x=32
x |= y
>>>x=32
x = null
y = null
x |= y
>>>x = 0;
function getDefaults(options,default_args)
{
for(var index in default_args)
{
if(typeof options[index] == "undefined") options[index] = default_args[index];
}
return options;
}
so now you can do something like
initialize:function(args)
{
args=getDefaults(args,{debug:false});
}
instance=new Class({debug:true});
I remember using something like "typeOf arg == 'undefined'" previously, but right now (testing out FF3) this doesn't work for me.
Hmm ...
eg, rather than
function war(enemy,reason) {
if(!enemy) { //The mandatory argument is not present - die with error(no pun intended)
alert("Please choose an enemy before starting a war");
return false;
}
if(!reason) { //If the optional argument is not there, create a new variable with that name.
var reason = "They have Nukes!";
}
/* ...Do what you want with the arguments... */
}
use this:
function war(enemy,reason) {
if( typeof enemy == 'undefined' ) {
alert("Please choose an enemy before starting a war");
return false;
}
if( typeof reason == 'undefined' ) {
var reason = "They have Nukes!";
}
/* ...Do what you want with the arguments... */
}
hope that helps
typeof(arg) === 'undefined'
The triple equals is 'exactly equal in value and type'. It avoids any unintended type coercion.
[code]
var foo = new Array();
foo[0] = 'bar';
foo[1] = 'baz';
foo.length;
>>2
var foo new Array();
foo['a'] = 'bar';
foo['b'] = 'baz';
foo.length;
>>0
[/code]
Because foo is an Array - "[]" is SHORTHAND for "new Array()", just like "{}" is SHORTHAND for "new Object()".
Do yourself a favor: pickup a copy of "JavaScript: The Good Parts" by Douglas Crockford (O'Reilly, ISBN# 978-0-596-5177-8) and see how real men write code.
//Better to check if it is undefined.
function foo(dummy,b,c){
b=(typeof(b)=="undefined")?"This is the default value of b.":b;
c=(typeof(c)=="undefined")?"You haven't passed the argument c!":c;
alert("dummy: "+dummy+"\nb: "+b+"\nc: "+c);
}
foo(); //Will alert:
/*
dummy: undefined
b: This is the default value of b.
c: You haven't passed the argument c!
*/
Functions like toData(), toText(), toHTML(), toJavaScript(), toCSharp(), etc., in addition to stock toString() calls should be common.
Ever call toString() on a javascript function? Done properly it will show you the function's source code. Everything should have something like that built in. Open Source FTW (for the win)!
http://skewsme.com/observations4.html#tables
The kicker to that is that the .length property of your object will not reflect the number of properties you've assigned - so you can't step through them with a for loop.
a, strong, em, b, i, code, pre, pandbrallowed. Other tags will be shown as code(< will become <). Urls, Line breaks will be auto-formated.