Jump to content


Check out our Community Blogs

dbug

Member Since 09 Sep 2010
Offline Last Active Apr 28 2012 08:55 AM
-----

Topics I've Started

JavaScript: Using lambda functions

11 September 2010 - 02:14 PM

I will try to do a brief introduction to lambda functions in JavaScript.

JavaScript has a nice feature that allows you to create anonymous functions and assign them to variables (also called lambda functions or lambda calculus). This can be used to do things like create functions that dynamically create other functions and return them as a result to be used in other parts of the script. This may be used to create very complex scripts, but the concepts are easy to understand and it's even very useful when programming in JavaScript.

Let's begin with a "normal" JavaScript function:

function cmp(num1, num2)
{
    if (num1 < num2)
    {
        return -1;
    }
    if (num1 > num2)
    {
        return 1;
    }
    return 0;
}
This is a very simple function named "cmp" that simply compares two numbers passed as arguments and return -1, 0 or 1 depending on which one is greater than the other.

Supose we have another function called "sort" that uses this one to sort an array of integers. Nothing strange till here. Supose now that we also need to sort an array of dates. Do we need to create another cmp function for dates and another sort function ?

Well, the new cmp function is absolutely necessary because the algorithm to compare two dates is different to the one of comparing two integers. But what about the sort function ? the algorithm is the same, only the comparison must be changed. Here we can use lambda functions.

JavaScript allows us to assign functions to variables, and pass these variables to functions as arguments. Let's see an example:

var cmp_ints = function(num1, num2)
              {
                  [I]<same code>[/I]
              }
We have created a new anonymous function (there is no name between the keyword "function" and the argument list, so it's anonymous) and assigned it to the variable cmp_ints.

We can use this variable as if it were a function:

var c1 = cmp_ints(4, 5); // will return -1
var c2 = cmp_ints(10, 2); // will return 1
Now we can create a sort function like this:

function sort(data, cmpfunc)
{
    for (i = 0; i < data.length; i++)
    {
        for (j = i + 1; j < data.length; j++)
        {
            if (cmpfunc(data[i], data[j]) > 0)
            {
                tmp = data[i];
                data[i] = data[j];
                data[j] = tmp;
            }
        }
    }
}

numbers = [ 5, 3, 8, 4 ];
sort(numbers, cmp_ints);
(Bubble sort is not the best sorting algorithm, but it's sufficient for the explanation)

Notice that we are using the variable cmp_ints (that contains our comparing function) as the second parameter for the sort function. This argument is used as if it were a normal function inside sort, passing the two numbers to compare between parenthesis. Now we can use exactly the same sort function with another comparing function:

var cmp_dates = function(date1, date2)
                {
                    return cmp_ints(date1.getTime(), date2.getTime());
                }
I converted the dates into numbers and then used the old cmp_ints function to compare them. Now I can call the sort function this way:

dates = [ new Date("10/12/2007 11:23"),
          new Date("1/8/2005 21:54"),
          new Date("4/1/2009 9:08"),
          new Date() ];
sort(dates, cmp_dates);
Now the sort function can sort the array of dates using the new cmp_dates function without coding anything else.

Another place where anonymous functions can be used is in callbacks. JavaScript allows you to define a function to be called after a period of time (a delay). If the action to execute when the timeout expires is not used anywhere else in the script, we can use a lambda function:

setTimeout(function()
           {
               alert('Timeout expired !!!');
           }, 1000);
This is a great way to define callbacks, and it is heavily used in some JavaScript frameworks, like jQuery.

One interesting thing about this way of defining callbacks is that the callback function can be inside the context of another function. This means that it can use the local variables and arguments of the containing function:

function alertDelayed(text, delay)
{
    setTimeout(function()
               {
                   alert(text);
               }, delay);
}

alertDelayed("Hello", 5000);
As you can see, I'm using the argument "text" inside the callback function, that will be executed after the termination of alertDelayed function. There is no theoretical limit in the number of nested functions that you might have, and each one has access to the context of all the previous functions in the hierarchy.

function doubleAlertDelayed(text1, text2, delay)
{
    setTimeout(function()
               {
                   alert(text1);
                   setTimeout(function()
                              {
                                  alert(text2);
                              }, delay);
               }, delay);
}

doubleAlertDelayed("Hello", "Goodbye", 5000);
Hope you liked it. If you have any questions, I'll try to answer them.

Hi

09 September 2010 - 01:02 PM

Hello, I'm a computer science engeneer and I've been programming since very young. I like it and now I decided to join to this forum to learn more and share my knowledge to try to help others where possible.

I hope to enjoy this site.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download