3

I've stumbled upon a pretty elegant way to structure JS Code for a page, though I'm not really sure why it works the way it does. Could someone explain to me how this works? (Why is that return statement there for example).

Also is there a name to describe a pattern like this?

var PageCode = (function () {

    return {
        ready: function () {
            console.log('document.ready');
        },
        load: function() {
            console.log('document.load');
        }
    };
}());

$(document).ready(PageCode.ready);
$(window).load(PageCode.load);
richie
  • 457
  • 1
  • 6
  • 19
  • It's called a `closure`. Googling `javascript closure` will give you a LOT of results. – MattDiamant Jul 28 '14 at 22:44
  • 3
    This is actually a particularly bad example of an immediately-invoked function expression (IIFE) since it has no local variables. You could just as easily have used the returned object literal in place of the whole IIFE without any observable changes in behavior. – cdhowie Jul 28 '14 at 22:45
  • This is the simple [JavaScript Module Pattern](http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html) – feeela Jul 28 '14 at 22:45

2 Answers2

5

The pattern is called Revealing Module Pattern, a variation of the Module Pattern where the return value is used to expose properties of the module to make them public.

The advantage in returning some values at the end is that you can define all variables and functions in the same way using var, instead of making them properties of the module. The returned object contains some of the previous defined variables to make them public (unlike in your example where the functions are defined in the return statement)

In the standard Module Pattern you would define private and public function like this:

var PageCode = (function () {

    var f1 = function() { /* ... */ }
    this.f2 = function() { /* ... */ }

}());

And for the Revealing Module Pattern the equivalent would be

var PageCode = (function () {

    var f1 = function() { /* ... */ }
    var f2 = function() { /* ... */ }

    return {
        f2: f2
    };
}());
kapex
  • 28,903
  • 6
  • 107
  • 121
  • This pattern along with the links at the top help a lot to clarify about what's going on. Also the link for the almost "duplicate" answer helps a lot as well. Thanks for the help! – richie Jul 28 '14 at 23:07
  • @richie In JavaScript functions implicit returns `undefined`. Explicit can returns everything, for example object. Returned value after IIFE calls will be assigned to variable that IIFE is assigned. After that you can call some methods on *PageCode* – Krzysztof Safjanowski Jul 28 '14 at 23:07
1

To help you understand this code , look at what goes after the return statement as an object

{
    ready: function () {
        console.log('document.ready');
    },
    load: function() {
        console.log('document.load');
    }
}

an object that has two items which are both functions. this object is returned and assigned to the variable PageCode, now you can call the frist function PageCode.ready(); and the second PageCode.load();

The $(document).ready(); and the $(window).load(); functions take as arguments functions, which are going to be executed when the document is ready and when the window is loaded. that's why you call them with functions as arguments

$(document).ready(PageCode.ready);
$(window).load(PageCode.load);
Khalid
  • 4,730
  • 5
  • 27
  • 50