Unlike many other languages, JavaScript does not support namespaces. Namespaces are important because they help reduce the number of identifiers for variables, objects, and functions that are added to the global scope in your application.
JavaScript is a flexible language and there are ways to work around this limitation and implement your own namespaces. First, let's explore the need for namespaces a bit more.
In JavaScript, all the code shares a single global namespace which is simply a single global object that holds all global variables and functions as properties.
In the browser this is the window object. This tends to pollute the global scope if you have many objects. In the example below, num, obj, str, total, numr, and sum are all added to the global object:
- var num = 5;
- var obj = {};
- var str = "Good morning";
- function sum(x, y){
- total = x + y;
- return total;
- }
- numr = sum(4,3);
Anything that is not properly declared, such as undeclared function variables, also ends up on the global object. In the example above, the identifiers num, obj, str, and sum are properly declared using the var keyword, but the function scoped variable total is missing a var and numr is a misspelling of num. JavaScript will add both total and numr to the global name space, which most likely is not what you want.
Suppose that your web app includes a third party JavaScript library that creates beautifully animated buttons. You deploy your app and the next thing you know is there are complaints from a client: they don't want 125,000 teddy bears.
You start investigating and after many hours of intense pressure you discover that the animation library uses a global variable named number to iterate over the animations. But you also use number to hold the number of items ordered in a shopping cart. This is an example of a name collision. Name collisions can create bugs that are often very hard to trace.
Name collisions can be a significant problem in JavaScript. So, how do you avoid this? A quick and easy solution is offered by the Namespace Design Pattern. You create a single global object for your application and add all your variables and functions to this object.
This allows you to namespace your code, make things tidier, and significantly reduce your chances of naming conflicts with third-party JavaScript libraries, widgets, etc.
Note that the namespace name itself is added to the global scope, so it is best that you create a unique name. Our example below uses MYAPP in uppercase, to emphasize the namespace.
- var MYAPP = {}; // our unique namespace
- MYAPP.num = 5;
- MYAPP.obj = {};
- MYAPP.str = "Good morning";
- MYAPP.sum = function(x, y){
- var total = x + y;
- return total;
- }
- MYAPP.num = MYAPP.sum(4,3);
The above namespace pattern is a great first step in avoiding potential name collisions. However, other, more sophisticated and robust patterns exist that can help you better manage namespaces in JavaScript.
No comments:
Post a Comment