From: vunet on 12 Feb 2010 14:53 I found the library with this constructor below. I would like to understand why is it used like this: within (function(){})(); constructor and no var declaration for SomeGlobalVar variable. What are the advantages and what does it mean? SomeGlobalVar = (function () { //code here })();
From: Stefan Weiss on 12 Feb 2010 15:24 On 12/02/10 20:53, vunet wrote: > I found the library with this constructor below. I would like to > understand why is it used like this: within (function(){})(); > constructor and no var declaration for SomeGlobalVar variable. What > are the advantages and what does it mean? > > SomeGlobalVar = (function () { > //code here > })(); The function here is used to create a new scope. It will be executed immediately (see the "()" at the end?) and return a value, which will then be assigned to SomeGlobalVar. All functions and variables declared inside this block will remain "private", i.e. not visible from the outside. This is what makes the pattern attractive, especially for modularized code - the global namespace will not be polluted with unnecessary identifiers. -- stefan
From: Stefan Weiss on 12 Feb 2010 15:37 On 12/02/10 20:53, vunet wrote: > I found the library with this constructor below. I would like to > understand why is it used like this: within (function(){})(); > constructor and no var declaration for SomeGlobalVar variable. What > are the advantages and what does it mean? > > SomeGlobalVar = (function () { > //code here > })(); I overlooked the part about the "no var declaration" in my previous reply. That's not part of the pattern, and if SomeGlobalVar hasn't been declared in whatever "the library" is, that's just plain bad style. By the way, didn't you ask this here before? <http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/6297ca62ecab08ef/74f6d2aa2db68b18> -- stefan
From: vunet on 12 Feb 2010 15:45 Thank you very much. Would you mind me asking for some brief clarifications? > All functions and variables declared inside this block will remain > "private", i.e. not visible from the outside. 1. But can we call SomeGlobalVar.doIt() from outside if it is set like: SomeGlobalVar = (function () { doIt : function(){} })(); 2. and why keyword "var" is omitted? Is it needed at all? 3. what is the example of polluting global namespaces with unnecessary identifiers? (only if it si easy to explain)
From: Scott Sauyet on 12 Feb 2010 15:54 On Feb 12, 2:53 pm, vunet <vunet...(a)gmail.com> wrote: > I found the library with this constructor below. I would like to > understand why is it used like this: within (function(){})(); > constructor and no var declaration for SomeGlobalVar variable. What > are the advantages and what does it mean? The basic idea is that global variables are evil. This technique moves what would otherwise be global variables into a closure [1], removing them from the global scope. For example, in the following code var count = 0; function createClickHandler(nbr) { return function() { alert("You clicked dead link " + (1 + nbr)); } } var links = document.getElementsByTagName("A"); for (var i = 0; i < links.length; i++) { var link = links[i]; if (link.getAttribute("href") == "#") { link.onclick = createClickHandler(count++); } } all the variables used are now available in the global scope, including "count", "links", the function "createClickHandler", and, perhaps surprisingly, "i" and "link". You can see for yourself by clicking the button on this page: http://scott.sauyet.com/Javascript/Demo/2009-06-22a/ If, however, you surround the code with "(function(){" and "})();", as you can see at http://scott.sauyet.com/Javascript/Demo/2009-06-22b/ the variables are no longer defined when you click the button. You've removed the variables from the global scope. As to the syntax, what you are seeing is an anonymous function created and then immediately applied. You could do this with a named function like this: function myFunc() { // code here } myFunc(); but then you've added "myFunc" to the global namespace. By removing the function name, you are adding nothing at all to the global namespace. Ideally, this would be accomplished with syntax more like this: function() { // code here }(); i.e., we create the function and apply it. But that syntax is not legal. For technical reasons, you need to surround the anonymous function with parentheses to be able to apply it with the "()" operator, and we end up with (function() { // code here })(); As to how closures manage to keep the global namespace clean, you will need to read up on closures. [1] Now if your code returned a value, you could assign the result to a variable, and anything nested in that closure would be available from there. So if you wanted to use the createClickHandler function, but you wanted it to be smart enough to manage it's own count, you could put it in its own closure like this: var createClickHandler = (function() { var count = 0; return function() { return function() { alert("You clicked dead link " + (++count)); }; }; })(); // later link.onclick = createClickHandler(); A version that does this is here: http://scott.sauyet.com/Javascript/Demo/2009-06-22c/ Note that "count" is not available to anything bu the function createClickHandler(). This has become a very common idiom in JavaScript programming, and it really is important to understand it if you want to work with any but the most basic of modern scripts. Cheers, -- Scott ____________________ [1] http://www.google.com/search?q=javascript+closure
|
Next
|
Last
Pages: 1 2 3 Prev: wordpress and modal commentary window Next: Not quite async XMLHttpRequest |