A deeper dive into the namespace pattern to refactor the global variables.
We all have heard or read that globals are bad practices.
Polluting the code space with multiple globals leads to unmanageable and unpredictable code. It is always advisable to keep the globals in check and have it as minimum as possible.
In this part, we will be discussing one approach that will reduce the global variables with much ease.
Suppose in your codebase the following globals are present —
// Constructors
function X() {}
function Y() {}
// global vars
var res = 1;
// global objects
var module1 = {
a: 1,
b: 2
};
var module2 = {};
module2.a = 10;
module2.b = 20;
var module3 = {};
In the above block, we have 6 global variables. Now, we can refactor this code to have only one global object, and all the constructors, variables, and objects will be part of it.
Ideally, all codebases should thrive to have a single global variable.
Having multiple globals are bad because of many reasons —
- they could be modified accidentally and are error-prone.
- also, it may cause name collision with your code or 3rd party library
Solution —
Refactored code —
// Global object
var APP = APP || {};
// Constructors
APP.X = function () {};
APP.Y = function () {};
// variables
APP.res = 1;
// objects
APP.modules.module1 = {a: 1, b: 2};
APP.modules.module2 = {};
APP.modules.module2.a = 10;
APP.modules.module2.b = 20;
APP.modules.module3 = {};
There is a problem with the code e.g if you want to use the below
var module1 = APP.modules.module1;
you have to make 3 checks like below
var module1 = APP && APP.modules && APP.modules.module1;
and this is kind of irritating.
To solve this we need to have a handy function that deals with the namespacing
part.
Let's call this function ‘namespace()’
and use it like this —
APP.namespace(‘APP.modules.module1’)
which is equivalent to —
var APP = {
modules: {
module1: {
}
}
};
Implementation of namespace() function
var APP = APP || {};
APP.namespace = function (str) {
var parts = str.split('.'),
parent = APP;
// remove the redundant global
if (parts[0] === 'APP') {
parts = parts.slice(1);
}
for (var i = 0; i < parts.length; i++) {
if (typeof parent[parts[i]] === 'undefined') {
parent[parts[i]] = {};
}
parent = parent[parts[i]];
}
return parent;
}
Let's test the above.
We can see that —
APP.namespace(‘APP.modules.module1’)
gives the desired result and also passing the APP (the top global object in the namespace)
is redundant. We can achieve the same by passing just modules.module1
APP.namespace(‘modules.module1’)
Let me know if you like the namespace pattern. If you like my article, please follow me. Thanks for reading the article, See you soon!
Top comments (0)