Computer >> Computer tutorials >  >> Programming >> Javascript

How to avoid namespace pollution in JavaScript?


Avoiding namespace pollution

Javascript don't support function overloading. So when any two functions with same name are used, one function will override the other function depending on the order these functions are loading. This means javascript lacks namespaces(naming convention). However, we can use objects to create namespaces so that we can avoid name collision.

var Tutorix = Tutorix || {};

The above line of code says that if Tutorix object is already present then use it, else create a new object.

We can also create nested namespaces that is a namespace inside another namespace.

var Tutorix = Tutorix || {};
Tutorix.TeamA1 = Tutorix.TeamA1 || {};

In the above lines of code second line suggests that if TeamA1 already exists use that object, else create an empty TeamA1 object.

In the following example even though we are passing only 2 parameters in the HTML file we are getting 3 parameters in the output. This is because of namespace collision that happen between Team1 and Team2(both are sharing same function name "student"). 

TeamA1.js

<html>
<body>
<script>
   function student(Fname,Lname){
      this.Fname = Fname;
      this.Lname = Lname;
      This.getFullName = function(){
         return this.Fname + " " + this.Lname;
      }
   }
</script>
</body>
</html>

TeamA2.js

<html>
<body>
<script>
   function student(Fname, Mname, Lname){
   this.Fname = Fname;
   this.Mname = Mname;
   this.Lname = Lname;
   This.getFullName = function(){
      return this.Fname + " " + this.Mname + " " + this.Lname;
   }
   }
</script>
</body>
</html>

HTML file

<html>
<head>
<script type = "javascript" src = "TeamA1.js"></script>
<script type = "javascript" src = "TeamA2.js"></script>
</head>
<body>
<div id = "resultDiv"></div>
<script>
   document.getElementById("resultDiv").innerHTML =
   new student("Rajendra", "prasad").getFullName();
</script>
</body>
</html>

Output

Rajendra prasad undefined.


Since namespace collision happen between TeamA1.js and TeamA2.js, even though we sent only 2 parameters "Rajendra" and "prasad"  so as to access TeamA1.js, we got 3 parameters "Rajendra prasad undefined" in the output. This is because TeamA2.js which has 3 parameters has overridden the TeamA1.js.

So to avoid this type of name collision we have to create name spaces using objects. 

TeamA1.js

In the following code namespace TeamA1 is created using another object called Tutorix.

<html>
<body>
<script>
   var Tutorix = Tutorix || {};
   Tutorix.TeamA1 = Tutorix.TeamA1 || {};
   Tutorix.TeamA1.student = function (Fname, Lname){
      this.Fname = Fname;
      this.Lname = Lname;
      this.getFullName = function(){
         return this.Fname + " " + this.Lname;
      }
      return this;
   }
</script>
</body>
</html>

TeamA2.js

In the following code namespace TeamA2 is created using another object called Tutorix.

<html>
<body>
<script>
   var Tutorix = Tutorix || {};
   Tutorix.TeamA2 = Tutorix.TeamA2 || {};
   Tutorix.TeamA2.student = function (Fname, Mname, Lname){
      this.Fname = Fname;
      this.Mname = Mname;
      this.Lname = Lname;
      this.getFullName = function(){
         return this.Fname + " " + this.Mname + " " + this.Lname;
      }
      return this;
   }
</script>
</body>
</html>

HTML file

Include both the js files(TeamA1.js and TeamA2.js) in HTML file.

<html>
<head>
<script type = "javascript" src = "TeamA1.js"></script>
<script type = "javascript" src = "TeamA2.js"></script>
</head>
<body>
<script>
   document.write(window.Tutorix.TeamA1.student("Rajendra", "prasad").getFullName());
   document.write(window.Tutorix.TeamA2.student("Babu","Rajendra","prasad").getFullName());
</script>
</body>
</html>

Output

Rajendra prasad
Babu Rajendra prasad

In the above example, we have used nested namespaces that is in Tutorix namespace we have nested TeamA1 and TeamA2 to avoid name collision. since namespace collision has avoided, we have got output for each individual scripts.