From: vunet on
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
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
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
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
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