1

I came across the following pattern recently:

/* PATTERN 1 */
(function(window) {
    var Stuff = (function() {  // Variable assignment and self-invoking anonymous function
        function Stuff(params) {
            this.items = [];
        }
        Stuff.prototype = {
            someMethod1: function() {

            },
            someMethod2: function() {

            }
        };
        return Stuff;
    }());  // END Variable assignment

    Stuff.create = function(params) {
        return new Stuff(params);
    };

    window.Stuff = Stuff;
}(window));

What confuses me is the role that assigning the Stuff variable plays. Specifically, how is this pattern operationally different to the following:

/* PATTERN 2 */
(function(window) {
        // No variable assignment or self-invoking anonymous function
        function Stuff(params) {
            this.items = [];
        }
        Stuff.prototype = {
            someMethod1: function() {

            },
            someMethod2: function() {

            }
        };

    Stuff.create = function(params) {
        return new Stuff(params);
    };

    window.Stuff = Stuff;
}(window));

Is the scope of pattern 1's prototype methods private in some way that pattern 2's prototype methods aren't? Is this purely a stylistic approach for more clearly separating business logic?

monners
  • 4,784
  • 2
  • 22
  • 44

2 Answers2

2

No difference at all. The inner IIFE is totally pointless, as it doesn't have any local variables, and can be safely omitted. The only (little) difference is that Stuff in the outer IIFE is now a function declaration, not a function assigned to a variable.

Of course, as it stands, the outer IEFE is quite useless as well, except maybe for code organisation.

Community
  • 1
  • 1
Bergi
  • 513,640
  • 108
  • 821
  • 1,164
2

Both patterns allows you to easily create true private variables that are attached to the Stuff "class", but can't be accessed outside of it:

var Stuff = (function() {  // Variable assignment and self-invoking anonymous function
    var stuff_private = "stuff";

    function Stuff(params) {
        this.items = [];
    }
    Stuff.prototype = {
        someMethod1: function() {

        },
        someMethod2: function() {

        }
        getStuff: function() {
            return stuff_private;
        }
    };
    return Stuff;
}());  // END Variable assignment

stuff_private is now embedded in the scope of Stuff, but it's invisible to the outside world. You could do this in the second pattern as well, but if you were creating multiple classes in the same file, each with their own private variables, then the first pattern might make sense.

Austin
  • 2,318
  • 2
  • 21
  • 33
  • 1
    The second pattern does allow this as well. The private variables would even be accessible to the static `Stuff.create` method! – Bergi Aug 15 '14 at 02:12
  • I guess that's true, so the only reason you would want the double wrapping is if you were going to create multiple classes in one file, each with their own private variables. – Austin Aug 15 '14 at 02:15
  • Maybe good to note that stuff_private is the same for all Stuff instances and all the methods now have a closure scope where stuff_private is accessible even the ones that never use it. – HMR Aug 15 '14 at 06:46