ACHIEVINGCODEPRIVACYWITHTHEMODULEP A T T E R N 20
2
Achieving Code Privacy with the
Module P a t t e r n
The more JavaScript there is in your codebase, the more your global scope
may get “polluted” with numerous functions and v a r i a b l e s that woul d
actually be better kept private to whatever set of code uses it. W i t h this
comes the risk of name collision, with one script unintentionally ov e r w r i t i n g
another’s identifiers. This leads to b u g s .
W e need to be able to create self-contained, opaque batches of JavaScript
code, which wo uld e x p o s e only selected identifiers, if any , to the outside
world. Indeed, this is a major requirement for “programming in the large,”
being able to bring in frameworks and libraries in any page without risking a
clash. This is what the module pattern is for.
The whole idea of the module pattern is to create a private scope for
v a r -declared identifiers and functions, a scope that only functions defined
inside it can access. T o make some of these definitions accessible to the
outside worl d , our enclosing function has two choices. It may return an
object with these selected v a l u e s as properties (see the facing page); we just
need to assign that returned object to a v a r i a b l e in the outside scope. Another
way is to pass the enclosing function a scope object that it writes properties
to (to make these global, you’ d simply pass window).
In JavaScript, identifiers first used with the v a r declaring keyword are local.
(They belong to the function currently defined.) Identifiers first used without
v a r are global. (They’ re grafted onto the current default scope, which most
of the time means the global window object.)
In a few specific circumstances, the current default scope will not actually be
global, so there are ways to e x e c u t e code in a context where non-v a r
identifiers will not leak into the global namespace—but that is a bit outside
the scope of this task.
T e c h n i c a l l y , you do not have to name your “public properties” ex a c t l y like
your private identifiers. Indeed, you could define public methods on the fly
in the returned object literal using anonymous functions. But such practices
would result in code that is more obscure (or misleading) to read
and—perhaps more importantly—to debug. As a rule of thumb, whenever
possible, try to define your functions using named function e x p r e s s i o n s :
function myFunctionName(...) { ... }
This makes for clearer code and helps a lot with the readability of the stack
traces when debugging your JavaScript.