Javascript

info

My home for all the weirdities of javascript

Self Executing - Anonymous Functions

I never understood these until I read an article by Mark Dalgleish

Consider this tiny piece of code

Anonymous functions
(function(){
  console.log('Hello World!');
})();

The above is a self executing block of code or a closure in javascript speak (not to be confused with a closure in Delphi or C++).  The magic here only happens because of the () at the end of the expression.  If you remove the (), the block does not self execute.

You can pass parameters to the ending (), these should match any parameters expected by the function() declaration see the following example

(function( x, y ){
  console.log(x + y);
})("Hello world", 52 );

When this executes the output will be Hello World52.  

I was trying to work out what was the advantage of this model over just writing a number function that could be called from anywhere because as a self executing function it can't be called from anywhere at anytime.  

According to MDN (Mozilla Developers Network) info on Closures, "closures are functions that refer to independent (free) variables (variables that are used locally, but defined in an enclosing scope). In other words, these functions 'remember' the environment in which they were created."

So the following piece of code demonstrates this quite nicely

example js code
function init() {
    var name = "Mozilla"; // name is a local variable created by init
    function displayName() { // displayName() is the inner function, a closure
        alert (name); // displayName() uses variable declared in the parent function    
    }
    displayName();    
}
init();

The function displayName() declared at line 3 is a closure, notice that it has access to it's enclosing environment.  When you run this code, the alert displays the message "Mozilla".  The function displayName() is able to access the variable name (line 2) because of what javascript terms lexical scoping, which describes how a parser resolves variable names when functions are nested. The word "lexical" refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available. Nested functions have access to variables declared in their outer scope.

Now consider the following piece of code

example js code
function makeFunc() {
  var name = 'Mozilla';
  function displayName() {
    alert(name);
  }
  return displayName;
}

var myFunc = makeFunc();
myFunc();

Line 6 returns a function name.  Like languages such as C and C++ using a function without the () yields the functions address, here it returns the a reference to the function that is then assigned to the variable myFunc at line 9.  The variable can then be used as function because once the RH value is assigned at line 9 the type of myFunc is assigned as a function reference. 

The reason this works is because all functions in javascript are closures.  closure is the combination of a function and the lexical environment within which that function was declared. This environment consists of any local variables that were in-scope at the time that the closure was created.  According to the MDN the reference to the lexical environment is passed back at line 6.

So what about this interesting piece of code

example js code
function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12

The function makeAdder creates a closure that takes a single parameter y.  This parameter should be supplied at the time when the closure is called.  

When lines 7 and 8 are invoked, they both pass the single values 5 and 10.  These values are stored in the closure that is created by makeAdder each time it is invoked, so the value of 5 and 10 are stored in each closure because according to the MDN the lexical environment persists even after the outer closure exits.  So when add5(2) is invoked at line 10, the value of 5 from line 7 has been retained, and similarly for add10(2) at line 11 and line 8 the value 10 has been retained.

This pattern is known in javascript as a function factory.