0

Still feel my understanding of Javascript closure is a little woolly at times and I would like to know if the code below represents closure in action...

function StateManager () {
    var self = this;

    this.state = null;

    $(document).on("internal_StateManager_getState", function () {
        return self.state;
    });

    $(document).on("internal_StateManager_setState", function (e, p) {
        if ( p && p.state ) {
            self.state = p.state
        }

        return self.state;
    });
};

new StateManager();

alert( $(document).triggerHandler("internal_StateManager_setState", { "state": 88 }) );

Is it accurate to say that this demonstrates closure because the state and self variables are accessable via the events? Thanks for any input!

so1
  • 185
  • 1
  • 9
  • I'm guessing you're referring to the "class", there are actually several closures in that code, jQuery creates a closure for each callback etc. when the `self` variable is accessed that way (outside it's lexical scope). – adeneo Aug 14 '14 at 15:44
  • Yes - the "class" is what I meant :) – so1 Aug 14 '14 at 15:47
  • 1
    The way the code is written, without any context etc. the class itself is not really a closure because it doesn't refer to variables outside it's lexical scope, so no. – adeneo Aug 14 '14 at 15:50
  • 1
    FWIW, theoretically every function in JavaScript is a closure, because every function has access to the variables defined outside of it. – Felix Kling Aug 14 '14 at 16:08
  • [`state` is not a variable, but a *property* of the `this`/`self` object](http://stackoverflow.com/q/13418669/1048572) – Bergi Aug 14 '14 at 16:32

1 Answers1

2

In the code in the question, the StateManager function does not create a closure, as it doesn't reference "free" variables from outside it's lexical scope.

However the jQuery callbacks are in fact closures, as they do reference the self variable which is defined outside the lexical scope of the callback functions.

A closure is, from MDN

Closures are functions that refer to independent (free) variables.

In other words, the function defined in the closure 'remembers' the environment in which it was created.

A simple example would be something like

function something() {

    var test = "Hello Kitty"; // "test" is a local variable created in this scope

    function otherFunc() { // this is an inner function, a closure
        alert( test ); // uses variable declared in the parent function
    }

}

That's about as simple as closure gets, it's just a function inside another function that uses variables outside it's lexical scope.

Another familiar example would be

$(document).ready(function() {  // creates outer scope

    var data = 'important stuff';

    $('.elems').on('click', function() { // this is a closure
         $(this).text( data ); // uses variable outside it's scope
    });

});
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • Thank you for that adeneo - it's the end of the work day for me but I will sleep on what you have said and see if it is all clear tomorrow :) – so1 Aug 14 '14 at 16:00