I am learning javascript and the module pattern, but I made a mistake in my code and it proved wrong some of the concepts I though were true about this pattern. My basic code is like this:
(function(window,$){
//global menu object
var menu = (function(){
//menu tab component
var tab = (function(){
//public properties
var tab = {
init:doStuff
}
//private properties
function doStuff(){
alert("initialising Tab")
}
//return public properties
return tab;
})();
//menu curtain component
var curtain = (function(){
//public properties
var curtain = {
init:doStuff
}
//private properties
function doStuff(){
alert("initialising Curtain")
}
//return public properties
return curtain;
})();
//menu content component
var content = (function(){
//public properties
var content = {
init:doStuff
}
//private properties
function doStuff(){
alert("initialising Content")
}
//return public properties
return content;
})();
//public properties
var menu = {
init:initialiseMenu
}
//private properties
function initialiseMenu(){
//initialise each component of the menu system
tab.init();
curtain.init();
content.init();
}
//final menu object
return menu;
})();
window.menu = menu;
})(window,jQuery);
Then When my page loads and the code is called:
menu.init();
It gives the alerts in order:
initialising tab
initialising curtain
initialising content
As I expect. But if I change the content component to be like this:
//menu content component
var content = (function(){
//public properties
var content = {
init:doStuff
}
//private properties
function doStuff(){
alert("initialising Content")
}
//CHECK ACCESS TO PREVIOUS VARIABLES
curtain.init();
//return public properties
return content;
})();
it gives out the alerts in order:
initialising curtain
initialising tab
initialising curtain
initialising content
So I see that it is able to access the curtain variable even though it wasn’t passed into the module as an argument.
I thought that each module would be self contained but I have discovered that this is not the case, Is there anyway to make a module only have access to variables you want it too? in particular to my example would be helpful,
Thanks Dan.
Each module is not self contained, rather, it creates a new scope that is a superset of the one in which it was created. The only thing that defines a new scope in Javascript is the
functionstatement. Within a new scope, everything from the outer scope is visible unless overridden by a variable of the same name. Nothing in the inner scope is visible to something outside it.The fact that your functions are self-executing doesn’t make a difference. Anything created in an outer scope will be visible in your inner scope, unless your create a new local variable of the same name which supercedes it.
As far as your inner scope is concerned, anything that was created outside it is much the same as a global. (And a global is just a variable created in the default scope, “window” in a browser).
You could think of an inner scope like being behind one-way glass. You can still see everything in the world, but the world can’t see you. And you can always choose to block the one-way glass so you can no longer see out. But nothing will ever be able to see in.