JS Closures

by Alon Rotem

HTML

<div id="logPane">
  <p>
    <strong>Log:</strong>
  </p>
</div>

JavaScript

function writeLine(str)
{
	$("#logPane").html($("#logPane").html() + str + "<br/>");
}

//The aim of this demo:
//To create a function that internally increments a stated counter on each call.
//This can be made by creating an object (a.k.a. function),
//but also with the right function closures.
//Alon Rotem, 2016

//Option 1: using a global variable.
//This would obviously work, because the variable's state is available everywhere.
var globalCounter = 0;
function countGlobally()
{
	writeLine("countGlobally: " + globalCounter);
	globalCounter++;
}
countGlobally();
countGlobally();
countGlobally();
writeLine("---------------------");

//Option 2: a function-scoped variable.
//This would not work, because the variable gets recreated and 
//re-assigned every time the function is called.
function coutLocally() {
    var localCounter = 0;
    writeLine("coutLocally: " + localCounter);
    localCounter++;
}
 coutLocally();
 coutLocally();
 coutLocally();
writeLine("----------------------");

//Option 3: Using a nested function.
//This would also not work, for the same reason the previous option does not.
function countWithNestedFunction() {
    var nestedFunctionCounter = 0;
    function increment() 
    {
	    writeLine("countWithNestedFunction: " + nestedFunctionCounter);
    	nestedFunctionCounter++; 
    }
    increment();
}
countWithNestedFunction();
countWithNestedFunction();
countWithNestedFunction();
writeLine("----------------------");

//Option 4: Using a closure - WORKS!
//Since the funciton automatically executes itself, it instantiates itself as an object, 
//stored in a variable. Each time it is called, it actually uses that instantiated variable.
//This happens automatically, before the call to countWithClosure() takes place.
//Thus, the function variable here, acts as a class private field, that gets kept.
//Calling the function countWithClosure(), immediately returns its nested funciton result,
//Which means, the variable gets  printed out and...