May 25, 2012
keyword that would make a property of an object private. All of the properties and methods of
create a private state and protect it. Module pattern has evolved over the course of almost 10 years and as a starting point I
am going to use revealing module pattern, which we in our development team just call the module pattern.
this pattern is that you can expose only the properties and methods that you want keeping the rest of them protected in the closure.
this pattern does not allow you to split the code into multiple files. All of the functions have to be within a single file. This
problem is easy to solve with the pattern below. I have also added a few methods and functions that help me demonstrate the beauty
of this approach.
This pattern allows the use of the module even before it is loaded. For example, in the course of your application, you need to
load a module as a separate script. However, before you load it, you want to pass a few variables to it.
In line 1, we declare the module variable as an empty object, if it was not declared before. Then, in lines 2-3 we set a few public
properties that will be passed to the module while it asynchronously loads. The content of the file module.js can be like this
You can augment this module at any time in the future. All you need to do is to repeat the basic structure of the module.
For example, if in addition to the code above you execute the following code
it will extend the module with doSomething()
The Prettiest Form
My favorite and, arguably, the most prettiest form of the module pattern with augmentation is achieved when we
it and pass the context.
Besides using call
to invoke the module, this version also uses functional declaration for internal methods, not functional
expressions. If you assign a function to a variable you cannot use this variable before it was declared. However, if you use functional
declarations, you can use them before they were declared. This allows to use functions and then exit the module with return this
while the implementation of the module follows below. In my view it makes the code easier to follow in large applications.
The Private Problem
There is one grave problem with the augmented module pattern that is hard to solve. The problem is that augmented portion of the
they have 2 different variable scopes and there is no way to share them.
Looking for a solution, I have come across an article
by Ben Cherry that proposes to solve this problem by sealing and unsealing the private variables. While this is a solution to the
problem, I do not think it is the prettiest one. The problems with this approach are numerous:
- As a developer you have an additional burden to seal and unseal private scope.
- Private scope must be encapsulated into an object or you would have to seal and unseal each and every variable.
- Private scope is not completely protected because anyone can seal and unseal it if they know what they are doing.
function. I am not a big fan of eval()
, but if it can solve the
problem it is worthwhile to give it a shot. Below is a simple example how eval()
can be used
At first I thought I can write a library where I can "hide" eval()
and it would do the job for me, but soon I have realized that
in order to access the private scope eval()
has to be executed where private scope is visible. Therefore, it must be used within the
module function or within any sub-function of the module function. On the bright side, you can also augment the module following the same
pattern and executing it with eval()
Lastly, there is one more resources I would recommend for further reading. Addy Osmani has written a book called
where he describes lots