This article shows classic design pattern with ECMAScript on how to organize javascript code with a structure that make possible to:
This structure is known globally as a module in javascript.
The early JavaScript implementation (such as ECMA-262 1)) add no means to organize code such as ESM module, this pattern were then found by developers to organize their code.
The Immediately invoked function expression (IIFE) is a common pattern that :
IIFE are also known as Anonymous Closure.
This pattern are also known as the module pattern
You can import via the argument.
For instance, if you want to have access to the global variable JQuery
(function ($) {
// now have access to globals jQuery (as $)
}(jQuery));
Example:
let module = (function () {
let exp = {}; // the public object that will be returned
let privateVariable = 1; // this variable stays in the function scope and is then private
// this function stays in the function scope and is then private
function privateMethod() {
// ...
}
exp.publicProperty = "public property !"; // the attached property is also public
exp.publicMethod = function () {
console.log("public method");
};
return exp;
}());
module.publicMethod();
console.log(module.publicProperty);
var GLOBAL_MODULE = (function (module) {
// Augmentation
module.newFunction= function(){
console.log("new function !")
}
// Overwrite
let oldOverwrittedMethod= module.overwrittedMethod;
module.overwrittedMethod = function(){
console.log("overitted method with access to the old method");
}
return module;
}(GLOBAL_MODULE || {}));
GLOBAL_MODULE.newFunction();
The definition of the GLOBAL_MODULE with var is important because it allows to pass it as argument even if it was not defined. If you use let or const, you would get the following error: Cannot access 'GLOBAL_MODULE' before initialization
The returned object of the IIFE becomes a property of the module.
MODULE.sub = (function () {
var my = {};
// ...
return my;
}());
A normal function can also be used.
This design pattern makes possible to implement a class (object) with the help of the closure capability of the Javascript function.
The function will behaves like a class but in a function structure.
The call to a module function will instantiate a new function with a new scope.
function User(name){
// Private
var username = name;
// Private
function returnName() {
return username;
}
// Public
var publicAPI = {
getName: returnName
};
return publicAPI;
}
// User() creates an instance of the User module
var foo = User("foo");
var bar = User("bar");
console.log( foo.getName()+" loves "+bar.getName() );
The new keyword was not used (ie new User()) because User is not a class to be instantiated, User() is just a function.
class are by default good candidate for module creation.