Category: Web

Simply Closures – Part I -> Preliminaries

To cover closures I’m going to do as Lewis Carroll said;

Begin at the beginning and go on till you come to the end: then stop.
- The King, Alice in Wonderland

This will make this a long post (update, posts!), but it will also hopefully set in place foundations that will make things much easier to understand.

Functions and Scope

Functions are at the core of closures, as they govern scope.
You see, most languages people are used to have block scope (C, C++, Objective-C, C#, Java etc)

example c# scope:


if (true) {
    string theVar = "inner";
}
Console.WriteLine(theVar); // compilation error
                   // theVar is not in scope

In javascript this code is fine, as the code is in the same function.


if (true) {
    var theVar = "inner";
}
alert(theVar); // this works

Functions can access their values and their parent functions values.
We will clarify this further in part II of this blog series. For now it is fine to note that block scope does not work in javascript, and that functions are what are crucial in delineating scope.

Therefore, functions in javascript are very important so we need to be specific about how we can declare them and call them. This understanding will serve as a foundation for understanding the more powerful features of closures in javascript.

There are two ways to declare functions in javascript:

// variation 1
function myFunction() {
   return 'hello world';
}

$(document).ready(function() {
   alert(myFunction());  // outputs hello world
   alert(window.myFunction());  // outputs hello world
});
// variation 2
var theFunction = myFunction() {
   return 'hello world';
}

$(document).ready(function() {
   alert(theFunction());  // outputs hello world
   alert(window.theFunction());  // outputs hello world
});

under-the-hood javascript assigns globals to window object, the first variation is really a convenience shortcut to the second variation, where it assigns the function to globals.

Self-Invoking Functions

We can call functions as soon as we declare them, by using the following notation.
This creates the function executes it then throws it away (ie we aren’t assigning the function to anything)

(function(){
  alert('This function is called once straight-away');
})();

The pattern being:

self-invoking function

Functions as Parameters (callback functions)

We can also pass functions to be called in ours or other peoples functions:

function addFunctionResults(a,b) {
   return a() + b();
}

function one() {
  return 1;
}

function two() {
  return 2;
}

$(document).ready(function() {
  alert(addFunctionResults(one, two));
});
// alternative version of the above
// using anonymous functions

function addFunctionResults(a,b) {
   return a() + b();
}

$(document).ready(function(e) {
  alert(addFunctionResults(function() { return 1; },
                           function() { return 2; })
         ); // returns 3
});

Inner Functions

We can utilise an inner function, or we can return it by an explicit return or by assigning it to a variable in parent function space, the latter two cause a closure (we break the scope chain). The preceding sentence will make sense once we begin talking about scope chains, for now, let us look at an example of inner functions that are utilised and inner functions that are returned.


$(document).ready(function() {

    alert(a('hello world'));

});

function a(param) {
    function b(theInput) {
        return param;
    };
    return 'you said "' + b(param) + '"';
}  

Returning an inner function:

  // returning an inner function
  function a() {
    alert('returning inner function');
    return function() {
      alert('b');
    };
  }
var innerFunction = a();
innerFunction();

// or if we do not need to save
// a reference to function (ie call only once)
a()();

So, when we return an inner function, we call it once to get the inner function, then we call again to call the inner function.
This trick is used by people to make private initialisations in a function.


function initA() {
    alert('A!'); // stuff here is private init
    return function() {
        alert('B!');
    };
}

$(document).ready(function() {
    var func = initA(); // init // outputs A!
    func(); // call function once // outputs B!
    func(); // call function a second time // outputs B!
});  

Or as a variation, here we can do init and overwrite our function:


function a() {
    alert('A!'); // stuff here is private init
    a = function() {
        alert('B!');
    };
}

$(document).ready(function() {
    a(); // init // outputs A!
    a(); // call function once // outputs B!
    a(); // call function a second time // outputs B!
});  

Here is part 2 of this series

WordPress Themes