Functions as Data

In JavaScript, functions can be assigned to variables, and variables are data. This is powerful.

Here’s a simple example:-

var say = alert;
say("hello"); //"hello"

Any function (native or otherwise) can be assigned to a variable. Adding parentheses to the variable will invoke it.

Any variable can be passed as an argument to a function, and since a variable can be a function, we can pass functions to other functions:-

function processRequest(userRequest, checkData, errorHandler) {
    var dataError = checkData(this.state);
    if (!dataError) {
        userRequest(this.state);
    } else {
        errorHandler(dataError);
    }
}

//save the report
processRequest(saveReport, checkReport, reportFailed);

In this example we defined a generic processRequest function in just a few lines. It takes three functions as arguments, which are responsible for defining all processing specifics: the request, the data verifier and the error handler. The processRequest function is fully extensible and customizable, and because it will be invoked by every request, there is a single, clean debugging point.

One more thing. Functions commonly enumerate collections of data in the form or arrays. What if the elements of such an array were also functions?

Here is a function that will format DOM elements based on a specified list of instructions, in this case an array of functions. Note the use of scriptaculous animation functions:-

var formatElement(elem, instructions) {
    for (var i=0; i<instructions.length; i++) {
        instructions[i](elem);
    }
}

var formatCorrectAnswer  = [
    function(elem) {elem.innerHTML="you are right!"}
    function(elem) {elem.className="correct"},
    function(elem) {Effect.Scale(elem,400)},
    function(elem) {Effect.Pulsate(elem, {pulses: 5, duration: 1.5 })
];

var formatIncorrectAnswer  = [
    function(elem) {elem.innerHTML="try again"}
    function(elem) {elem.className="incorrect"},
    function(elem) {Effect.Scale(elem,200)},
    function(elem) {Effect.Shake(elem, {pulses: 2, duration: 1.5 })
];

formatElement(myElement, answer.correct ? formatCorrectAnswer : formatIncorrectAnswer);

(disclaimer: garish effects for illustration only)

These are just a few examples of what you can do when you treat functions atomically. There are many more real world applications that I encourage you to seek out. As always your feedback is very welcome.

About these ads

One thought on “Functions as Data

  1. This is pretty cool. I ran into an odd thing with this though.

    tester

    function do_it() {
    var sFunctionName = document.getElementById(‘id1′).value;
    //document.write(sFunctionName);
    sFunctionName();
    }
    function test() {
    document.write(“test”);
    }

    In this example, the test function is not called when you select the test option. If you uncomment “//document.write(sFunctionName);”, you can see that sFunctionName = test when you select the “tester” menu item of the select. Do you have any idea why this wouldn’t work?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s