DEV Community

Cover image for How to Refactor the global variables in javascript?
Ajay Kumar Verma
Ajay Kumar Verma

Posted on

How to Refactor the global variables in javascript?

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 = {};
Enter fullscreen mode Exit fullscreen mode

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 —

  1. they could be modified accidentally and are error-prone.
  2. 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 = {};
Enter fullscreen mode Exit fullscreen mode

There is a problem with the code e.g if you want to use the below

var module1 = APP.modules.module1;
Enter fullscreen mode Exit fullscreen mode

you have to make 3 checks like below

var module1 = APP && APP.modules && APP.modules.module1;
Enter fullscreen mode Exit fullscreen mode

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’) 
Enter fullscreen mode Exit fullscreen mode

which is equivalent to —

var APP = {
   modules: {
      module1: {
      }
   }
};

Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

Let's test the above.

Refactoring global variables

We can see that —

APP.namespace(‘APP.modules.module1’)
Enter fullscreen mode Exit fullscreen mode

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’)
Enter fullscreen mode Exit fullscreen mode

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!

Discussion (0)