As I had already mentioned in my earlier blog that global variables and functions are prone to being overwrite by outside world (javascript). Therefore by reducing the number of globals in your code you are actually making an honest approach towards improving your code quality.
First of all, here in my blog I will talk about is what did I mean when I said "Global variables and functions are evil". I guess rather that talking theory, I would sound more logical if I give you a practical example. Suppose you have written one javascript file which provides a number of utility functions, among them is one for concatenating two strings. Let the code be something like below:
First of all, here in my blog I will talk about is what did I mean when I said "Global variables and functions are evil". I guess rather that talking theory, I would sound more logical if I give you a practical example. Suppose you have written one javascript file which provides a number of utility functions, among them is one for concatenating two strings. Let the code be something like below:
function concatenate(first_string, second_string, opertator) {
if(operator){
switch(operator){
case "+" :
return (var1.toString()+" "+var2.toString());
case "-" :
return (var1.toString()+" - "+var2.toString());
default :
return;
}
}
}
if(operator){
switch(operator){
case "+" :
return (var1.toString()+" "+var2.toString());
case "-" :
return (var1.toString()+" - "+var2.toString());
default :
return;
}
}
}
Now that you have written your javascript code, create one html file and import your js file to it.
Let us check that your function works fine or not in the html file that you created. So inside script tag you define the following js code:
Let us check that your function works fine or not in the html file that you created. So inside script tag you define the following js code:
var appendedString= concat("test1", "test2", "-");
console.log(appendedString); /* writes 'test1 - test2' on the console*/
console.log(appendedString); /* writes 'test1 - test2' on the console*/
Now create another javascript file and create a function having the same name as "concatenate"
function concatenate(first_string, second_string) {
return (var1.toString()+" "+var2.toString());+" "+"new"
}
return (var1.toString()+" "+var2.toString());+" "+"new"
}
Now include both the files in your HTML page. Let the second JS file be included after the first one.
Again try to access the function "concatenate".
Do you feel that since there are two functions with same name include in your html file then your browser or javascript interpreter will throw an error?
If your answer is "yes" then please check out in console that what has happened:
Again try to access the function "concatenate".
Do you feel that since there are two functions with same name include in your html file then your browser or javascript interpreter will throw an error?
If your answer is "yes" then please check out in console that what has happened:
var appendedString= concat("test1", "test2", "-");
console.log(appendedString); /* writes 'test1 test2 new' on the console*/
console.log(appendedString); /* writes 'test1 test2 new' on the console*/
Now I guess I have explained you why is it said that "Global variables and functions are evil" :)
In the example above both of the javascript files have a global function having same name. You included both the files in your page. And then what happened is that the function defined in the second file overwrite the function defined in the first file.
Now guess what might happen in very large projects where there are so many js files included in a single page .... :P
Therefore try avoiding them.
Now comes the discussion that how do I avoid global variables and functions...
There are certain approaches to it that you can follow. I will discuss about a few of them.
Suppose that your javascript file contains the following piece of code
In the example above both of the javascript files have a global function having same name. You included both the files in your page. And then what happened is that the function defined in the second file overwrite the function defined in the first file.
Now guess what might happen in very large projects where there are so many js files included in a single page .... :P
Therefore try avoiding them.
Now comes the discussion that how do I avoid global variables and functions...
There are certain approaches to it that you can follow. I will discuss about a few of them.
- Object Literal
- Immediately Invoked-function Expression
Suppose that your javascript file contains the following piece of code
var status= null;
function initialize(){....}
function update(){....}
function end(){....}
function initialize(){....}
function update(){....}
function end(){....}
You have three global functions and one global variable in your file.
Object Literal Approach
The first approach to protect it from being overwritten will be to use "object literal"
Object Literal Approach
The first approach to protect it from being overwritten will be to use "object literal"
var myNameSpace={;
status: null,
initialize : function(){....},
update : function(){....},
end : function(){....}
}
status: null,
initialize : function(){....},
update : function(){....},
end : function(){....}
}
Now here only a single global variable compare to your initial code in which there were actually four globals. Thus lowering the risk of collision in the name of global variables and functions. The biggest challenge with the single global variable pattern is ensuring that no one else has used the same global variable name as you have in the page. Therefore you may prefix namespacing. It's a simple concept at heart, but the idea is you select a unique prefix namespace you wish to use and then define any methods, variables or other objects after the prefix
One can also opt for adding properties directly to the namespace:
One can also opt for adding properties directly to the namespace:
var myNameSpace={;
status: null,
}
myNameSpace.initialize = function(){....},
myNameSpace.update = function(){....},
myNameSpace.end = function(){....}
status: null,
}
myNameSpace.initialize = function(){....},
myNameSpace.update = function(){....},
myNameSpace.end = function(){....}
Now if you wish to make a call to the function all you have to do is to make a call using the global object name:
myNameSpace.initialize();
myNameSpace.update();
myNameSpace.end();
myNameSpace.update();
myNameSpace.end();
2.)Immediately Invoked-function Expression
The second approach is to use IIFE. An IIFE is effectively an unnamed function which is immediately invoked after it's been defined.In Javascript function invocation provides an easy means to achieving privacy. If you don’t need any of your variables or functions to be available to the outside, simply wrap the whole construct in another set of parentheses to execute it without assigning any name to it:
The second approach is to use IIFE. An IIFE is effectively an unnamed function which is immediately invoked after it's been defined.In Javascript function invocation provides an easy means to achieving privacy. If you don’t need any of your variables or functions to be available to the outside, simply wrap the whole construct in another set of parentheses to execute it without assigning any name to it:
(function()
var status= null;
function initialize(){....}
function update(){....}
function end(){....}
)()
var status= null;
function initialize(){....}
function update(){....}
function end(){....}
)()
This keeps everything in a tidy little package that is inaccessible to the outside world, but very easy to share variables and functions inside of.
Since none of these are available from the outside at all any more, if you want to make them available you need to wrap the things you want to make public in a return statement:
Since none of these are available from the outside at all any more, if you want to make them available you need to wrap the things you want to make public in a return statement:
var myNameSpace = (function()
var status= null;
function initialize(){....}
function update(){....}
function end(){....}
return{
initialize:initialize,
update:update,
end:end,
}
)()
var status= null;
function initialize(){....}
function update(){....}
function end(){....}
return{
initialize:initialize,
update:update,
end:end,
}
)()
That is all from my side for this topic.
Don't forget to check some of the great approaches discussed in Peter Michaux blog regarding Javascript namespacing.
Happy Coding :)
Refences:
Javascript Namespacing
Immeiately Invoked-function Expresion
Don't forget to check some of the great approaches discussed in Peter Michaux blog regarding Javascript namespacing.
Happy Coding :)
Refences:
Javascript Namespacing
Immeiately Invoked-function Expresion