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...