JavaScript global namespaces

I have recently run into a problem that I had by accident two functions with the same name from separate JavaScript files in my page.

It can happen that multiple developers are working on separate user controls contained in one page. Each user control references a separate JavaScript file so it stays reusable together with its client-side functionality. But then developer A names a function in his JavaScript file init() but developer B has already declared a function init() in a different file.

The developers don’t know from each other’s code and add both user controls in the same page. This means that both init functions are declared globally in one page.

In this situation the last one overwrites the previous one but the developer who added the first one will not be happy about it.

Most of the times we don’t even know that another developer has declared a function with the same name in another JavaScript file referenced in one of the many user controls on the same page.

For example these general function names are often used:

   1: function confirm() {

   2:

   3: }

   4: function validate() {

   5:

   6: }

   7: function init()

   8: {

   9:

  10: }

  11: function getValue()

  12: {

  13:

  14: }

But when the errors come, that will be fun to figure out.

This problem is best described here ( JavaScript Best Practices ):

Avoid Cluttering The Global Namespace: Global variables and functions are rarely required. Using globals may cause naming conflicts between javascript source files and cause code to break. For this reason, it is a good practice to encapsulate functionality within a single global namespace. The simplest approach is to create a single global object and assign properties and methods to this object.

Creating A Namespace

   1: var MyLib = {}; // global Object cointainer

   2: MyLib.value = 1;

   3: MyLib.increment = function() { 

   4:     MyLib.value++; 

   5: }

   6: MyLib.show = function() { 

   7:     alert(MyLib.value); 

   8: }

   9:  

  10: MyLib.value=6;

  11: MyLib.increment();

  12: MyLib.show(); // alerts 7

Another solution would be using the JavaScript Programming Patterns.

Here’s a really good overview of the current patterns with examples: JavaScript Programming Patterns

I guess all of you will recognize the Old-School Way, which is actually the bad way I described in the situation above.

The patterns described in the above link are good ways to encapsulate big pieces of code, but be careful when using them. If the object/module is instantiated multiple times, also the contained methods are defined multiple times. So then the performance drops.

The other (simpler) option is to create unique namespaces for each javascript files with Type.RegisterNamespace ( Type.registerNamespace Method ).

This is how we use it in our projects, for example a sample content of JavaScript file:

   1: Type.registerNamespace

   2:     ("SolutionNameClientScript.Make.It.Unique");

   3:  

   4: SolutionNameClientScript.Make.It.Unique = {

   5:       init: function() {

   6:         ...

   7:     },

   8:       confirm: function() {

   9:         ...

  10:     },

  11:       calculate: function() {

  12:         ...

  13:     }},

  14:       validate: function() {

  15:         ...

  16:     }

  17: };

  18: $().ready(function(){

  19:       SolutionNameClientScript.Make.It.Unique.init();

20: });

 

   1: <asp:Button ID="SomeButton" runat="server" 

   2:     CssClass="nwaCtrlFormSubmitButton" 

   3:     Text="Do something!" 

   4:     OnClick="SomeButtonClick" 

   5: OnClientClick=

   6: "SolutionNameClientScript.Make.It.Unique.calculate();"

   7: />

   8:  

   9: <asp:CustomValidator 

  10:     ID="SomeValidator" 

  11:     runat="server" 

  12: ClientValidationFunction=

  13: "SolutionNameClientScript.Make.It.Unique.validate" 

  14:/>

 

Other resources which I found helpful:

Advertisements