JavaScript Module Pattern with Example

JavaScript module pattern with example

In order to approach to Modular design pattern, you need to understand these concept first:

Immediately-Invoked Function Expression (IIFE):

(function() {
// Your code goes here
}());

There are two ways you can use the functions. 1. Function declaration 2. Function expression.

Here are using function expression.

What is namespace?
Now if we add the namespace to the above piece of code then

var anoyn = (function() {
}());

What is closure in JS?

It means if we declare any function with any variable scope/inside another function (in JS we can declare a function inside another function!) then it will count that function scope always. This means that any variable in outer function will be read always. It will not read the global variable (if any) with the same name. This is also one of the objective of using modular design pattern avoiding naming conflict.

var scope = "I am global";
function whatismyscope() {
var scope = "I am just a local";
function func() {return scope;}
return func;
}
whatismyscope()()

Now we will apply these three concepts I mentioned above to define our first modular design pattern:

var modularpattern = (function() {
// your module code goes here
var sum = 0 ;

return {
add:function() {
sum = sum + 1;
return sum;
},
reset:function() {
return sum = 0;
}
}
}());
alert(modularpattern.add()); // alerts: 1
alert(modularpattern.add()); // alerts: 2
alert(modularpattern.reset()); // alerts: 0

jsfiddle for the code above.

The objective is to hide the variable accessibility from the outside world.

JavaScript design pattern: difference between module pattern and revealing module pattern?

There are at least three different ways to implement the Module Pattern, but the Revealing Module Pattern is the only Module Pattern descendant that has an official name.

The Basic Module Pattern

The Module Pattern must satisfy the following:

  • Private members live in the closure.
  • Public members are exposed in the return object.

But there's a lot of ambiguity in this definition. By resolving the ambiguity differently, you get variants of the Module Pattern.

The Revealing Module Pattern

The Revealing Module Pattern is the most famous and most popular of the Module Pattern variants. It has a number of advantages over the other alternatives, such as

  • Rename public functions without changing function body.
  • Change members from public to private or vice versa by modifying a single line, without changing the function body.

The RMP satisfies three additional conditions in addition to those in the original:

  • All members, whether public or private, are defined in the closure.
  • The return object is an object literal with no function definitions. All right hand side expressions are closure variables
  • All references are via the closure variables, not the return object.

The following example shows how it's used

var welcomeModule = (function(){
var name = "John";
var hello = function(){ console.log("Hello, " + name + "!");}
var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
return {
name: name,
sayHello: hello,
sayWelcome: welcome
}
})();

If you wanted to make name and sayHello private, you just need to comment out the appropriate lines in the return object.

var welcomeModule = (function(){
var name = "John";
var hello = function(){ console.log("Hello, " + name + "!");}
var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
return {
//name: name,
//sayHello: hello,
sayWelcome: welcome
}
})();

The Module Pattern with Object Literal

This is probably the oldest variant of the Module Pattern. Unlike RMP, there's no sexy official name for this variant.

It satisfies the following conditions, in addition to the original:

  • Private members are defined in the closure.
  • Public members are defined in the return object literal.
  • References to public members are via this, whenever possible.

In the following example, you can see how, in contrast to RMP, the function definitions are actually in the return object literal, and references to members are qualified by this.

var welcomeModule = (function(){
return {
name: "John",
sayHello: function(){ console.log("Hello, " + this.name + "!");}
sayWelcome: function() { console.log( this.hello() + " Welcome to StackOverflow!");}
}
})();

Note that unlike RMP, in order to make name and sayHello private, the references pointing to name and sayHello in the various function body definitions also have to be changed.

var welcomeModule = (function(){
var name = "John";
var sayHello = function(){ console.log("Hello, " + name + "!");};
return {
//name: "John",
//sayHello: function(){ console.log("Hello, " + this.name + "!");}
sayWelcome: function() { console.log( hello() + " Welcome to StackOverflow!");}
}
})();

The Module Pattern with Return Object Stub

This variant also has no official name.

It satisfies the following conditions, in addition to the original:

  • An empty return object stub is defined at the beginning.
  • Private members are defined in the closure.
  • Public members are defined as members of the stub
  • References to public members are via the stub object

Using our old example, you can see that public members are directly added to the stub object.

var welcomeModule = (function(){
var stub = {};
stub.name = "John";
stub.sayHello = function(){ console.log("Hello, " + stub.name + "!");}
stub.sayWelcome = function() { console.log( stub.hello() + " Welcome to StackOverflow!");}
return stub;
})();

If you want to make name and sayHello private as before, the references to the now-private members have to be changed.

var welcomeModule = (function(){
var stub = {};
var name = "John";
var sayHello = function(){ console.log("Hello, " + name + "!");}

stub.sayWelcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
return stub;
})();

Summary

The differences between the Revealing Module Pattern and the other variants of the Module Pattern is primarily in how public members are referenced. As a result, RMP is much easier to use and modify, which accounts for its popularity. However, these advantages come at a great cost (in my opinion), which Addy Osmani alludes to in his post on the Revealing Module Pattern,

A disadvantage of this pattern is that if a private function refers to a public function, that public function can't be overridden if a patch is necessary. This is because the private function will continue to refer to the private implementation and the pattern doesn't apply to public members, only to functions.

Public object members which refer to private variables are also subject to the no-patch rule notes above.

As a result of this, modules created with the Revealing Module pattern may be more fragile than those created with the original Module pattern, so care should be taken during usage.

and which I've talked about in some other posts.

Javascript 'normal' objects vs module pattern

If you're only going to be using one instance per page, I don't see the need to involve the new keyword. So personally I would create a revealing module like you did in your last example, and expose an object with the "public" properties.

Though I don't see your point with the getModel() function, since MyModel is obviously accessable outside of the scope.

I would have rewritten it slightly:

var LoginModel = (function(model, window, undefined){

function init(){ } // or whatever

function doSomethingWithModel(){
console.log(model);
}

return { init: init };

})(MyModel, window);

If you're uncertain of which modules that will get a model, you can use loose augumentation and change

})(MyModel, window);

to

})(MyModel || {}, window);

If you need several instances of a module, it would look something like this:

var LoginModel = (function(model, window, undefined){

function loginModel(name){ // constructor
this.name = name; // something instance specific
}

loginModel.prototype.getName = function(){
return this.name;
};

return loginModel;

})(MyModel, window);

var lm1 = new LoginModel('foo');
var lm2 = new LoginModel('bar');

console.log(lm1.getName(), lm2.getName()); // 'foo', 'bar'

how to use the javascript module pattern in a real example?

This is quite an opinionated subject, but I'd do it (without entirely knowing your full app and what it does), somewhat like so:

var myApp = (function() {

var someElement = $("#foo"); //some element I know I'll use lots

var addMessage = function(message) {
$.ajax({
url: '/test',
type: 'POST',
dataType: "json",
data: {'message' : message},
success: function(data) {
...
},
error: function() {
...
}
});
};

var inputClick = function(event) {
event.preventDefault();
//depending on if you'll reuse these selectors throughout the app I might have these as variables
$('.loading').html('<img class="remove_loading" src="/graphics/loading.gif" />');

var message = $(".wallmessage").val();

if (message == ""){
$("#messageempty").jmNotify();
$('.remove_loading').remove();
} else {
addMessage(message);
}
};

var bindFunctions = function() {
$("input#share").on("click", inputClick)
};

var init = function() {
bindFunctions();
};

return {
// EDIT: 27/12/16 - need to return init for 'usage' example to work
init: init,
addMessage: addMessage
//anything else you want available
//through myApp.function()
//or expose variables here too
};

})();

//usage

myApp.init();

Your original code for the pattern is wrong, the function has to have () at the very end, to make it a function that is immediately invoked, and then executes, exposing anything through the return statement.

You may wish to differ slightly from what I've done, it's only a basic idea but I hope it might get you started.

Someone a while back asked a question relating to this pattern and I answered it explaining why we use (function() {})(); and how the return statement works in that context, if you're slightly confused by it that might be worth reading too.

why module pattern?

I think this example could help you to clarify the usefulness of the Module Pattern.

Module Pattern

The module pattern is widely used because it provides structure and helps organize
your code as it grows. Unlike other languages, JavaScript doesn’t have special syntax
for packages, but the module pattern provides the tools to create self-contained decoupled
pieces of code, which can be treated as black boxes of functionality and added,
replaced, or removed according to the (ever-changing) requirements of the software
you’re writing.

The module pattern is a combination of several patterns, namely:

  • Namespaces
  • Immediate functions
  • Private and privileged members
  • Declaring dependencies

The first step is setting up a namespace. Let’s use the namespace() function from earlier
in this chapter and start an example utility module that provides useful array methods:

MYAPP.namespace('MYAPP.utilities.array');

The next step is defining the module. The pattern uses an immediate function that will
provide private scope if privacy is needed. The immediate function returns an object - the actual module with its public interface, which will be available to the consumers of
the module:

 MYAPP.utilities.array = (function () {
return {
// todo...
};
}());

Next, let’s add some methods to the public interface:

MYAPP.utilities.array = (function () {
return {
inArray: function (needle, haystack) {
// ...
},
isArray: function (a) {
// ...
}
};
}());

Using the private scope provided by the immediate function, you can declare some
private properties and methods as needed. Right at the top of the immediate function
will also be the place to declare any dependencies your module might have. Following
the variable declarations, you can optionally place any one-off initialization code that
helps set up the module. The final result is an object returned by the immediate function
that contains the public API of your module:

MYAPP.namespace('MYAPP.utilities.array');
MYAPP.utilities.array = (function () {
// dependencies
var uobj = MYAPP.utilities.object,
ulang = MYAPP.utilities.lang,
// private properties
array_string = "[object Array]",
ops = Object.prototype.toString;
// private methods
// ...
// end var
// optionally one-time init procedures
// ...
// public API
return {
inArray: function (needle, haystack) {
for (var i = 0, max = haystack.length; i < max; i += 1) {
if (haystack[i] === needle) {
return true;
}
}
},
isArray: function (a) {
return ops.call(a) === array_string;
}
// ... more methods and properties
};
}());

The module pattern is a widely used and highly recommended way to organize your
code, especially as it grows.

“JavaScript Patterns, by Stoyan Stefanov
(O’Reilly). Copyright 2010 Yahoo!, Inc., 9780596806750

Javascript Module Pattern with anonymous functions

It seems like you need to understand how return works in functions in order to understand why the provided examples behave the way they do.

Example 1: You create a new variable pub and adding two methods to it: add and sub. At the end, you're returning the pub variable to CalcModule

So when you call CalcModule, it returns the following object with two methods:

CalcModule = {
add: function() {...},
sub: function() {...}
}

Example 2: Let's rewrite example 2 similar to example 1...

var testModule = (function () {

var counter = 0;
var pub;

pub.incrementCounter: function () {
return counter++;
}

pub.resetCounter: function () {
console.log( "counter value prior to reset: " + counter );
counter = 0;
}

return pub;
})();

We know pub is an object...

pub = {
incrementCounter: function() { ... },
resetCounter: function() { ... }
}

and we're returning pub to testModule... therefore...

testModule = {
incrementCounter: function() {...},
resetCounter: function() {...}
}

Hope this is helpful.

JavaScript Module Pattern - Private variables vs. Static variables

You're right; _name is more of a static variable. It is kept in the closure that contains the constructor, so every use of the constructor will use that same variable. And remember, this has nothing to do with classes, and everything to do with closures and functions. It can be pretty handy, but it isn't how you do private members.

Unsurprisingly, Douglas Crockford has a page devoted to private members in Javascript.

In order to make private members, you have to go 'one level deeper'. Don't use a closure outside of the constructor; use the constructor as the closure. Any variables or methods defined inside the constructor are obviously not usable by the outside world. In fact, they aren't accessible by the object, either, so they are rather extremely 'private'.

We want to use our private members though. :) So what to do?

Well, in the constructor, do this:

var Klass = function () {
var private = 3;
this.privileged = function () { return private; };
};

and then:

var k = Klass();
console.log(k.privileged()); // 3

See how that's using the constructor as a closure? this.privileged lives on, attached to the object, and thus private lives on, inside this.privileged's closure.

Unfortunately, there's one problem with private and privileged methods in Javascript. They must be instantiated from scratch each time. There is no code sharing. That's obviously what we want with private members, but it isn't ideal for methods. Using them slows down object instantiation and uses more memory. It's something to keep in mind when/if you run into efficiency problems.

(Revealing) Module Pattern, public variables and return-statement

Does this actually mean, that I can't have any methods, that handle public properties?

No, it means that you cannot have public variables. var _public is a variable, and it is not accessible from outside, and when you modify the private variable this will not be reflected in your public ._public property.

If you want to make things public, use properties:

var a = function() {
var _private = null;
function init() {
_private = 'private';
this._public = 'public';
}
function getPrivate() {
return _private;
}
return {
_public : null,
init : init,
getPrivate : getPrivate,
}
}();

I can manipulate that public property, like a._public = 'public';. But I can't change it from within my object.

You can use this in the methods of your object, as shown above. Or you use a to reference the object, or possibly even store a local reference to the object you return. See here for the differences.

Or at least those changes aren't passed through

Yes, because variables are different from properties (unlike in some other languages like Java, and with exceptions for global ones). When you export public: _public in your object literal, it takes only the current value from the _public variable and creates a property on the object with it. There is no persistent reference to the variable, and changes to one are not reflected in the other.

Why isn't it possible to just use return this; to make everything public? As this should be the context of the self-invoked function, shouldn't it just return eveyrthing in it?

Variables are part of a scope in JavaScript. (Except for the global one) those scopes are not objects accessible to the language.

The this keyword does not refer to this scope of the function, but to the context that was provided by the call. That can be the base reference in a method call, the new instance in a constructor invocation, or just nothing in a basic function call like yours (or the global window object in loose mode).

Module Pattern still necessary now that javascript has native 'classes

The module pattern isn't only (or even primarily) used to mimic classes. It's proper modules, not classes, that make the old module pattern likely to become...if not obsolete, then a lot less-used, in the next few years. Those and private methods (which are currently a Stage 3 proposal) and perhaps to an extent private fields (also Stage 3).

But prior to proper modules, or sometimes even concurrent with them, you'd still use it if you want to have private functions or data or similar related to something which isn't private. Example:

const Foo = (function() {
function privateFunction(x) {
return /*...do something with `x`...*/;
}

class Foo {
dosomething(x) {
return privateFunction(x) ? "a" : "b";
}
}
return Foo;
})();

I'll also note that sometimes, you might use an anonymous block rather than an IIFE, since class, const, and let have block scope. I wouldn't above because I'd have to make the outer Foo non-constant (so I could assign to it in the block), but there are other times when it might apply...



Related Topics



Leave a reply



Submit