JS tip - Avoiding polluting the global namespace

Neeraj Singh

By Neeraj Singh

on March 18, 2009

I am learning Javascript and as I do more Javascript work I am learning not only the language but also the best practices. Today I am developing a Javascript calendar. In the process of creating the calendar I created a bunch of utility functions that are available at global namespace.

What are we talking about

My main concern is that as Javascript develeoper I should not be polluting global namespace. I could write the calendar code like this.

1showCalendar = function (options, d) {};
2
3calendarHeaderMonth = function (opts) {};
4
5calendarHeaderWeek = function (opts) {};
6
7calendarData = function (opts) {};
8
9drawCalendar = function (opts, d) {};
10
11getCellID = function (year, month, day) {};
12
13// use showCalendar
14showCalendar({}, new Date());

You can see that the main method that I want to expose to global namespace is showCalendar. However I am also exposing six other functions to global namespace. It means that if some user has declared a global namespace function named getCellID then my getCellID is going to collide with the user's function. This is not good.

Goal

The goal is to refactor the code in such a way that only one method showCalendar is exposed to the global namespace. In order to test the code at the very end of the javascript I will invoke a call to method getCellID.

1showCalendar = function (options, d) {};
2
3calendarHeaderMonth = function (opts) {};
4
5calendarHeaderWeek = function (opts) {};
6
7calendarData = function (opts) {};
8
9drawCalendar = function (opts, d) {};
10
11getCellID = function (year, month, day) {};
12
13// use showCalendar
14showCalendar({}, new Date());
15
16// this call should fail but is not failing now
17getCellID(2009, 5, 4);

The above call to getCellID is currently being executed successfully. It means I have polluted the global namespace. I am going to fix it.

Solution

The solution is to put all the code inside a function. In a function all the variables and functions declared are scoped only to that function. Out of that function, inner functions cannot be used. Inside this function only one method showCalendar would be exposed.

Here is the solution.

1(function () {
2  // by not declaring var this variable is going to be at global namespace
3  showCalendar = function (options, d) {};
4
5  var calendarHeaderMonth = function (opts) {};
6
7  var calendarHeaderWeek = function (opts) {};
8
9  var calendarData = function (opts) {};
10
11  var drawCalendar = function (opts, d) {};
12
13  var getCellID = function (year, month, day) {};
14})();
15
16showCalendar({}, new Date());
17
18// this call will fail
19getCellID(2009, 5, 4);

In the above case the call to showCalendar was successful. However call to getCallID failed. That's good. It means I am not polluting the global namespace.

If you notice carefully in the above case after declaring an anonymous function I am invoking that function by having () at the end. You can read more about self-invoking function here .

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, ReactJS, React Native, remote work,open source, engineering & design.