1

I have been in constant search for the most simple Javascript module pattern. I have read pretty much every article I can find. Most module patterns like to create an object, add functions to it, then return that object and expose the public methods, like this:

var Module = (function() {
    var exports = {}, x = 1;

    function private() {
        return x;
    }

    exports.public = function() {
        return x;
    };

    return exports;
}());

This seems like over the long term it may be a pain, so I was looking for an easier way. I've seen that I can call apply to the function, and pass in an object, then use "this" to reference it and return "this" for the same effect, like this:

var Module = (function() {
    var x = 1;

    function private() {
        return x;
    }

    this.public = function() {
        return x;
    };

    return this;
}).apply({});

Is there anything wrong with using apply and passing in an empty object? This seems like the best way as the "this" keyword goes nicely with JS Intellisense coloring, and seems to be easier to understand. Anybody see any problems with this or have a simpler way?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
wayofthefuture
  • 8,339
  • 7
  • 36
  • 53
  • How is someone supposed to answer this? If you run the code and it works, then it's good, right? What are you looking to get as an answer? – Tech Savant May 12 '15 at 01:21
  • There is nothing wrong with that. – Ram May 12 '15 at 01:21
  • Different way to implement module is [here](http://stackoverflow.com/questions/29533532/different-ways-to-implement-one-module-in-javascript) – zangw May 12 '15 at 01:25
  • @NotoriousPet0 I don't want to find out I'm not doing it properly 1000 hours into restructuring a HUGE project. Thanks – wayofthefuture May 12 '15 at 01:32
  • @scuzzlebuzzle Conceptual questions are better suited to another site, like Programmers maybe, Overflow is for specific problems with your code. Not theory or concept. Thanks – Tech Savant May 12 '15 at 01:38

1 Answers1

1

This seems like the best way as the "this" keyword goes nicely with JS Intellisense coloring

That really shouldn't be an argument for anything :-)

seems to be easier to understand.

Not to me, actually. this is typically used in constructors and in object methods only, not in IEFEs (unless it refers to the same as this outside of the IEFE, i.e. the global object). So to understand what you are doing here, I'd have to scroll down to the end of the file to find out how the function is called.

Anybody see any problems with this

Yes. Apart from being unusual, it deprives you of a static, local reference to your module object. If you want to call one of your public methods from somewhere in your module, you can use this (inside other public methods) or Module, but neither of them works the same as exports.

or have a simpler way?

You could also mix the two patterns:

var Module = (function(exports) {
    var x = 1;

    function private() {
        return x;
    }

    exports.public = function() {
        return x;
    };

    return exports;
}({}));
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 1
    Hm, that `Mod` function makes it even more intransparent what is happening (if you don't know the function) – Bergi May 12 '15 at 02:02
  • So... ur saying the public method inside the module is not accessible from the private method, because the "this" is referring to something else in the private method. Then I guess that means using "exports" is the only way to make those public functions accessible to private functions in the module, right? – wayofthefuture May 12 '15 at 02:03
  • 1
    @scuzzlebuzzle: Yes, inside `private` you could use `exports.public()` or `Module.public()`, but if you wanted to use `this.public()` you'd have to `.bind(this)` all your functions. – Bergi May 12 '15 at 02:03
  • Great, thanks for saving me alot of trouble. Now I think all I'm going to do is replace "exports" in your answer to "_" ..... will mark this as answer now thanks – wayofthefuture May 12 '15 at 02:06
  • 1
    Hm, better use something descriptive like `exports` than just `_`. Or just use [an abbreviation for] the actual name of your module. – Bergi May 12 '15 at 02:08
  • 1
    Of course, after all it is *your* code base and you have to understand your code. If you establish a pattern that works for you (and has no functionality drawbacks), if you document that pattern so fellow developers can take off it, and if you are consistent in your usage of the pattern, then *use whatever you like*. – Bergi May 12 '15 at 02:22
  • Not sure if I'm allowed to ask this, but we are looking for consultation services. Would you be interested in phone consultation for an hourly rate? We're looking for help before we start this javascript project restructure. Thanks – wayofthefuture May 12 '15 at 19:46
  • Sorry, I'm not a consultant and even if I were, I don't think I'd like to discuss JS on the phone :-) – Bergi May 12 '15 at 20:22