Privacy thru functions
If you read the entry Javascript scoping: things to keep in mind, you certainly remember that it is possible to create scoping thru functions, therefore, the following variables won't be available outside of the scope of the function:
function privacy() { var myvar=1; // can't be accessed from outside myvar =2: // can be accessed from outside }We can create a function by putting a reference to it in a variable too :
privacy = function() { var myvar=1; // can't be accessed from outside myvar2 =2: // can be accessed from outside } alert(myvar); //error alert(myvar2); //error privacy(); alert(myvar); //error alert(myvar2); //2We are using an anonymous function which definition is referenced to the privacy variable that will act like a normal function now.
But as you can see we need to call the privacy function in order to access the public variable we have created. It won't be available as long as we do not execute the function.
Closures as scope container
There is a way to create scoping without even having to name the function at all. we just need to define the anonymous function and have it execute right away.
we can do this, thanks to the following notation:
(function () { //your code here })();This is just an anonymous function held within a block. By doing so, the code defined in the anonymous function will be executed right away and therefore, what is defined within it will be available to us.
Let's try:
(function() { alert('hi!'); })();If you try this code, you get the alert prompt saying hi!.
In fact within this closure, you can write your javascript code like you always do!!
It will create a space hold in memory but not accessible from outside.
Well unless, you allow variables to be accessed from outside:
(function() { var myvar=1; // can't be accessed from outside myvar =2: // can be accessed from outside })();Closures are a very powerfull tool allowing many many other things!
Packages and closure : creating privacy for us, the lazy!
we have seen different packages holding some utilities function developped so far. There is especially one of them that has a dependency to an other package, the number package. Let's see the package in question:
JAME.Package('JAME.Util.Color'); JAME.Util.Color = { rgb2h:function (r,g,b) { var d2h = JAME.Util.Number.d2h; return [d2h(r),d2h(g),d2h(b)]; }, h2rgb:function (h,e,x) { var h2d = JAME.Util.Number.h2d; return [h2d(h),h2d(e),h2d(x)]; }, cssColor2rgb:function (color) { if(color.indexOf('rgb')<=-1) { return this.hexStr2rgbArray(color); } return this.rgbStr2rgbArray(color); }, hexStr2rgbArray:function (color) { return this.h2rgb(color.substring(1,3), color.substring(3,5), color.substring(5,7)); }, rgbStr2rgbArray:function (color) { return color.substring(4,color.length-1).split(','); }, Export : function() { JAME.Exporter(this); } };You can see that we have created a shortcut for 2 functions.
We have placed them within the function definition in order not to put them into the global space.
it was fine, because we only need them in one place but if we had them used in different places? Create a property into the object definition to hold them could be a solution but will polluate the package a little.
In that case, it is easier to create a closure to hold all the dependencies we require, therefore we can rewrite it this way:
JAME.Package('JAME.Util.Color'); (function () { var d2h = JAME.Util.Number.d2h; var h2d = JAME.Util.Number.h2d; JAME.Util.Color = { rgb2h:function (r,g,b) { return [d2h(r),d2h(g),d2h(b)]; }, h2rgb:function (h,e,x) { return [h2d(h),h2d(e),h2d(x)]; }, cssColor2rgb:function (color) { if(color.indexOf('rgb')<=-1) { return this.hexStr2rgbArray(color); } return this.rgbStr2rgbArray(color); }, hexStr2rgbArray:function (color) { return this.h2rgb(color.substring(1,3), color.substring(3,5), color.substring(5,7)); }, rgbStr2rgbArray:function (color) { return color.substring(4,color.length-1).split(','); }, Export : function() { JAME.Exporter(this); } }; })();the 2 shortcuts won't be available outside and therefore will keep the global space clean while allowing less typo!
Conclusion
You should be aware that a closure will keep everything defined in it and that it will stay in memory as long as the program goes. It can also lead to memory leaks especially in IE when mixed with DOM manipulation.
It is therefore a very powerfull tool but can have underisable effects that won't be noticable right away.
1 comment:
Hi,
thanks for reading.
I am not really sure of what you want to do but the following code just work fine here:
var com ={}
com.util={};
com.util.greeting = function(str) {
return 'hello '+str;
};
(function() {
var greeting = com.util.greeting;
MyObj = function() {
};
MyObj.prototype.someMethod = function() {
alert(greeting('world!'));
};
}) ();
var testing = new MyObj();
testing.someMethod();
Is it what you're trying to do?
Post a Comment