JS - Closures

by Charlie Winfrey

JavaScript

// Example 1: A most basic example

function foo() {

    var runCount = 0;

    function bar() {
        runCount++;
        console.log("Count is:", runCount);
    }

    // return reference to bar, not invoking it
    return bar;

}

var barReference = foo();
barReference();
barReference();

return;


// Example 2: Spare global, save memory, everyone wins...
//
// Here we have a function that returns a name based on a digit
// and we have the names array and a function that accesses it directly
//
// NOT great, because "names" is global
//
var names = ["ryan", "jess", "larry"]; // global
var digit_name = function (i) {
    return names[i];
}

// So lets make the variable local to the function
// this works... 
// but it is slow because it re-allocates the array on every function call
var digit_names = function (i) {
    var names = ["ryan", "jess", "larry"]
    return names[i];
}

// wrapping it in a function may do the trick
// now it's a closure, and we're not re-instantiating the names array on each call
// and in fact they are now private to the closed function
var getDigitNames = function () {
    var names = ["ryan", "jess", "larry"];

    function digit_names(i) {
        return names[i];
    }
    return digit_names;
}

var digit_names = getDigitNames();

// But we can optimize this by immediately invoking our function
// avoid having to create getDigitNames and use it
// This is called an Immediately Invoked Function Expression
var digit_name = (function () {
    var names = ["ryan", "jess", "larry"];

    return function (i) {
        return names[i];
    };
}());

console.log(digit_name(2));

// Example 3: APIs
// 
// We don't have to return a function; 
// we can also just return an object
// with the constructor function

var Letter = function (message) {

    var secretMessage = message.secret || undefined;

    //console.log(secretMessage);
    message = message.message || message;

    return {
        getMessage: function () {
           ...