JavaScript Jems - Functions Are Objects
Written by Mike James   
Wednesday, 08 November 2023
Article Index
JavaScript Jems - Functions Are Objects
Passing Functions
Function Properties

Passing Functions

The first is the characteristic most often associated with “first class functions”. As a function is an object you can use a function anywhere you can use an object. In particular, you can pass a function to another function. For example:

var myFunction=function(a,b){
  var answer=a+b;
  return answer;
}
var myAlerter(c){
  alert(c(2,3));
}
myAlerter(myFunction);

In myAlerter, c is a standard parameter and we pass myFunction as an argument. The variable myFunction is a reference to the function object we created and hence c is a reference to the same object. In the call to alert, c(2,3) calls the function passed into the myAlerter function.

Notice that there is another key idea here. If variable o references an object then o(parameters) calls the object as a function – which of course only works if the object is a Function object, aka a callable object.

As you can return an object from a function, you can also return a function object. For example:

var myAlerter(c){
  alert(c(2,3));
  return c;
}
var f=myAlerter(myFunction);

Following this f is a reference to the same function object as myFunction. It can be used simply by writing f(1,2).

Lifetime And Closure

In most cases a function that returns a function usually creates the function it returns. For example:

var funFactory=function(myValue){
                  var myAdd=function(a){
                              var result=a+myValue;
                              return result;
                            }
                   return myAdd;
                }

Notice that you can create functions within functions and so on. By the rules for local variables the inner function has access to the variables in the outer function, but not vice versa. That is, myAdd can use myValue, but funFactory cannot use result.

Now consider:

var myF=funFactory(3);

now myF references a function object with the code:

function(a){
   var result=a+myValue;
   return result;
}

 

If we call myF:

alert(myF(4));

the result is 7. This all seems perfectly reasonable until you start to look more closely at what is happening.

When we called funFactory it created a new function object. At the time that the function object was being created it had access to myValue because, as well as being a parameter, it is also a local variable. This is fine, but notice that when we call myF, which references the function object funFactory is not being executed – it finished when it returned the function object. By the usual rules, all local variables are destroyed when a function stops executing. So in principle, calling myF should result in an error as myValue no longer exists.

If this was the case we would have a problem in that now what a function does, or even if the function works, depends on when it is called. If it is called within funFactory then no problem because all the local variables it uses exist and are available to it. If it is called from anywhere else, after funFactory has finished running, then it crashes because the local variables that were available to it are no longer available.

A function should work irrespective of where is is called and so we are forced to invent the idea of closure. A closure captures the variables that are in scope when a function object is created. These captured variables exist for as long as the function object exists, i.e. they have the same lifetime.

As a side effect, variables in a closure are not accessible to any other part of the program. From the point of view of the rest of the program the closure variables were destroyed some time ago. This means that a function object can use variable that it has access to in a closure as a private variable.

Notice that closure is needed because functions are objects and they live for longer than just when they are being executed. In languages where functions are not objects there is no sense in which they exist when they are not executing and hence closure isn't a natural idea.

There is much more to say about closures and how they can be useful, but now you know why they are needed.

kindlecover

 



Last Updated ( Wednesday, 08 November 2023 )