Modules are used to mimic classes and focus on public and private access to variables and functions. Modules help in reducing the global scope pollution. Effective use of modules can reduce name collisions across a large code base. A typical format that this pattern takes is as follows:
Var moduleName=function() { //private state //private functions return { //public state //public variables } }
There are two requirements to implement this pattern in the preceding format:
Check the following example of a module:
var superModule = (function (){ var secret = 'supersecretkey'; var passcode = 'nuke'; function getSecret() { console.log( secret ); } function getPassCode() { console.log( passcode ); } return { getSecret: getSecret, getPassCode: getPassCode }; })(); superModule.getSecret(); superModule.getPassCode();
This example satisfies both the conditions. Firstly, we create an IIFE or a named function to act as an outer enclosure. The variables defined will remain private because they are scoped in the function. We return the public functions to make sure that we have a closure over the private scope. Using IIFE in the module pattern will actually result in a singleton instance of this function. If you want to create multiple instances, you can create named function expressions as part of the module as well.
We will keep exploring various facets of functional aspects of JavaScript and closures in particular. There can be a lot of imaginative uses of such elegant constructs. An effective way to understand various patterns is to study the code of popular libraries and practice writing these patterns in your code.
As in the previous chapter, we will conclude this discussion with certain stylistic considerations. Again, these are generally accepted guidelines and not rules—feel free to deviate from them if you have reason to believe otherwise:
// bad const foo = function () { }; // good function foo() { }
arguments
. This will take precedence over the arguments
object that is given to every function scope.