Creating Functions on the Fly

Summary

It is occasionally necessary to create custom unique functions on the fly in JS code at run time. This article details the various ways functions may be created on the fly.

Ways of defining a function

There are two ways to define a function in JS...although enough many people don't know about the versatility of the common method it might be more correct to say there are three ways:

The function Keyword

This is by far the more common method (and far easier) method of defining a function in JS. The syntax is:

function functionName (parameterList){ statementList }

function
This required keyword tells JS that you are defining a function.
functionName
This is the name of the function you wish to define and is, surprisingly to many people, optional. "What?" you say? More on this below.
parameterList
An optional list of variable names, separated by commas, which are created as local variables when the function is run and assigned values as passed to the function.
statementList
The meat of the function, these are the commands it executes when it runs.

So, most people define their functions up-front with this method, supplying the function name like this:

function GreetEveryoneAndVIP(vipName){
	alert('Hello World! Special greetings to '+vipName);
}

What this really does is create a variable named 'GreetEveryoneAndVIP' in the current context, which for web browsers is the window object. When you invoke the function in a web browser by calling GreetEveryoneAndVIP('Mr. President'), it is the same as if you wrote window.GreetEveryoneAndVIP('Mr. President'). [That the window object is the default object is also the reason that you can write alert(...) instead of window.alert(...), even though alert() is a method of the window object.]

Now, above I said that the name of the function is optional. This is called creating an anonymous function, and seems to make little sense; if you don't provide a name to the functions, how do you tell them apart when wanting to call one instead of another? The answer lies in the fact that the function keyword returns a reference to the function object when it is finished. By assigning this value of function a variable, you provide a way to differentiate the functions and call them on demand. So, the above function can be written identically this way: window.GreetEveryoneAndVIP = function(vipName){ alert('Hello World! Special greetings to '+vipName) };

Why would you want do that? Well...you wouldn't. Not when defining global functions, anyhow. That just plain ugly. But, there definitely are cases where this is very useful, and that's when you're creating methods of an existing object. I'll get into that below in Useful cases for anonymous functions, after I tell you about the other way of defining a function.

The new Function constructor

The other way to create a function is to use the new Function constructor:

funcObj = new Function( [param1,param2,...,paramN,] statementList);

funcObj
Like the function keyword, the new Function constructor returns a reference to the created function. To be useful, you have to assign it to something to be invoked later.
new Function(...)
This invokes the new Function constructor which returns the function object.
param1...paramN
You tell the function the name of the local parameter values by passing strings in as the names, separated by commas. (See the example below.)
statementList
As above, this is the code which the object should execute when run. However, unlike defining a function with the function keyword, these statements are all inside a single string passed to the new Function constructor.

Creating our example function with this method looks like this:

var GreetEveryoneAndVIP = new Function('vipName',"alert('Hello World! Special greetings to '+vipName)");

Having to put the the body of the function inside a single string can be rather annoying, but it allows you to create the body of the function on the fly based on values available in code, through string concatenation. (More on this later. I know, all the exciting stuff is at the end.) Using this method is akin to using eval(), which is to say, "ick". So avoid this method of creating functions if you can.

Useful cases for anonymous functions

So, I've given you the basics of how to create functions, but haven't really been clear about why you'd want to do anything other than the standard function foo(...){ ... } way. Those of you who haven't had to create functions on the fly are possibly saying, "Sure, you can create functions with arbitrary code bodies. So what? I can also do that by calling a single function and passing in different values for the parameters and changing what the function does based on that." To which I must respond: "Agch-ha! But what if you can't control the values to pass in?"

Event Handler Functions

When the web browser invokes an event handler for an object, you don't get to specify what parameters it passes along. If you can get away with an event handler that knows what to do based on the information available to it, that's great. For example, the following (IE-specific) code snippet uses a single function to alert the src of every image on the page when you click on it:

function SayMyName(obj){ 
	if (obj==null && event && event.srcElement) obj=event.srcElement;
	alert(obj.src);
}
var allImages = document.getElementsByTagName('img');
for (var i=0,len=allImages.length;i<len;i++) allImages[i].onclick=SayMyName;

(For those who haven't passed function references around before, note that there are no parenthesis after SayMyName above when assigning it to the onclick event. Putting () after a function/method causes it to run...without the parenthesis a reference to the function is passed around.)

Now, let's say that you'd like each image, when clicked upon, to tell you what number it is. You could modify the above SayMyName function to loop through the collection of all images every time it's called and stop when it find the current image, but that's very wasteful when you already know the image number on the first pass. Instead, it's time for an anonymous function, created on the fly! (Feel the excitement!)


	var allImages = document.getElementsByTagName('img');
	for (var i=0,len=allImages.length;i<len;i++) allImages[i].onclick=new Function("alert('Hey, I am image #"+i+"...sweet, eh?')");

Once you wrap your head around the two sets of string delimiters used there, you'll see that this is not passing the variable i to the function, but instead sticking it inline into the string the alert function yells out. The body of each of these functions is unique.

Now, it's all well and fine to create the body of the function each time

Custom Wrapper Functions

Referring to external objects in anonymous functions