Javascript Jems - Lambda expressions
Written by Ian Elliot   
Tuesday, 14 January 2014
Article Index
Javascript Jems - Lambda expressions
Using anonymous functions and invocation

JavaScript has lambda expressions in all but name. Find out how they work and how to use them.

 

Lambda expressions sound advanced and impressive and just about every language has them or is adding them. Put simply lambda expressions are something of a buzz word, so much that it's difficult to know what they really are all about. 

One place you wont hear much about lambda expressions is in JavaScript. You will hear it said that JavaScript doesn't do lambda expressions but this isn't the whole truth. 

First what is a Lambda expression?

Lambda expressions were invented by Church and Kleene, two great computer scientists, back in the 1930s. In practice this is fairly irrelevant in the sense that when most programmers use the term Lambda expression they mean a function of a number of parameters that returns a single result and can be passed to other functions.

The parameters and single result clearly aren’t a problem but what about passing a function to other functions?

This sounds more complicated but it's no problem in Javascript.

Javascript is an interpreted language and this means that it treats code and data much the same.

jemsicon

Functions As Objects

What this means in practice is that a variable can store data or code with the only real difference being that code can be executed using, for example the invocation operator ().

The usual way to define a Javascript function covers up this unity.

For example, the definition:

function test(a){
 alert(a);
}

looks like a standard function as you might find in any language but in JavaScript it is quite a lot more. 

In JavaScript a function is an object just like any other object and you can use a function anywhere you can use an object. 

This is often summarised by saying that functions in JavaScript are "first class" objects.

Contrast this to what happens in many other languages where functions are something completely different from an object and are usually thought of as being constituent parts of an object aka methods. This approach is what makes it necessary to introduce lambda expressions or something similar in these other languages. Put simply we need lambda expressions to provide us with functions that have a life for their own outside of objects and so that they can be passed around like objects.

Notice that it is possible to program in JavaScript and still come to the conclusion that functions are something special and different from objects. The reason for this is that JavaScript provides the standard syntax for a function declaration which allows you to ignore the fact that a function is an object.  

The alternative way of defining a function as a function expression makes it much clearer that it is more like an object:

var test=function(a){alert(a);};

You really can think of test as being a variable that just happens to hold a reference to a function object. 

It is important to know that JavaScript treats functions defined using the standard function definition somewhat differently to those defined in function expressions. In particular functions are subject to hoisting where function expressions are not. See JavaScript Hoisting Explained       

Of course a function object is special among objects in that it has a chunk of code, a method if you like, that you can invoke using the invocation operator on the object. 

That is test is a reference to an object and 

test("Hello") 

calls the function you defined. It really can help to think of this as the object's default method.  If you don't see what this idea is about consider adding a method to the function object:

test.myMethod=function(a){alert(a);};

You can now call myMethod using the usual:

test.myMethod("Hello");

and this makes

test("Hello");

look even more like a call to a default method. 

Finally also notice that in JavaScript object methods are just properties that happen to be function objects - nothing special here so move on...

Assigning Functions

As a function is just an object you can do anything you can do to an object to a function. 

For example you can assign one function to another using standard syntax:

var test2=test;
test2("hello2");

and this works perfectly.

Notice that while test and test2 are both references to the same function object and hence the same code, 

In short variables that happen to reference a function object behave like perfectly standard reference variables. 

In particular if you redefine test a new function object and block of code is created on the heap and test is set to point to it. The second variable, test2 still points to the original block of code and hence the old version of the function.

For example following:

test=function(){alert("Hello1");};
test2=test;
test=function(){alert("Hello2");};

test is a function that prints Hello2 but test2 is still the original function that prints Hello1, as you can confirm by using:

test();
test2();

In this sense JavaScript functions are immutable – you can’t modify them only create completely new functions. 

You can use this function reference mechanism to create something that looks like C#’s multi-target delegate function.

To call multiple functions with a single call you could use something like:

func1=function(){list of instructions 1};
func2=function(){list of instructions 2};
func3=function(){list of instructions 3};
func={func1();func2();func3()};

and to call all three functions one after another you would use:

func();

This looks like just calling the three functions one after another but of course func1, func2 and func3 are variables and hence you can dynamically change what functions are called.

You can pass parameters if you want to and pass them on to the sequence of called functions. This is all particularly useful if you want to implement a “callback” that invokes multiple functions.  If you want to allow users to add callback functions all you need to do is setup a stack or an array to store them as they are added.

Passing functions

Given you can pass an object, i.e. as a parameter, into a function it now seems entirely reasonable that  you can pass a variable that just happens to reference a function object into another function.

Recall that all parameters in JavaScript are passed by reference so just a pointer to the function is passed and this is efficient.

For example, the Array object has a method that will sort the array into order:

var list=new Array("A","AB","ABC","ABCD");
list.sort();
for(var i=0;i<list.length  ;i++){
 alert(list[i]);
}

What is perhaps slightly less well known is that the sort method can also take an optional function which it will use to compare the values of the array. This function is defined as:

function(a,b)

and it has to return a negative value if a<b, 0 if a==b and a positive value if a>b.

For example:

compare=function(a,b){
 return a.length-b.length;
}

used in

list.sort(compare);

sorts the list of strings into order based on their length alone.

Other languages that don't have first class functions have to resort to delegate types - object wrappers for functions - or lambda expressions.

 

Banner

<ASIN:1449316859>

<ASIN:0321572602>

<ASIN:0596806752>

<ASIN:1590597273>

<ASIN:059680279X>



Last Updated ( Tuesday, 28 October 2014 )