The (function (){ })(); Constructor

V

vunet

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
})();
 
V

vunet

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)
 
S

Scott Sauyet

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;
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
 
S

Stevo

Scott said:
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],
As to how closures manage to keep the global namespace clean, you will
need to read up on closures. [1]
Cheers,
-- Scott

You might want to read up on closures too. Using that syntax discussed
doesn't automatically create a closure. A closure is only created if it
returns a reference to a variable or function. A closure is where a
reference is kept to something that might otherwise have been destroyed
or garbage collected but is kept alive due to the external reference to
it. Well, that's how I understand them anyway.
 
D

Dmitry A. Soshnikov

The basic idea is that global variables are evil.  This technique
moves what would otherwise be global variables into a closure [1],
As to how closures manage to keep the global namespace clean, you will
need to read up on closures. [1]
Cheers,
   -- Scott

You might want to read up on closures too. Using that syntax discussed
doesn't automatically create a closure. A closure is only created if it
returns a reference to a variable or function. A closure is where a
reference is kept to something that might otherwise have been destroyed
or garbage collected but is kept alive due to the external reference to
it. Well, that's how I understand them anyway.

Well, technically and by the specification every (FD, FE, NFE and even
created directly via Function constructor) function in ECMAScript is a
closure. On implementation level however some optimization can be
made: if scope chain doesn't contain free variables, maybe local
variable can be stored in sort of stack-based system (which is faster)
rather than in heap (which is slower, but this is the way for
closures, as the idea of closures cannot be applied in stack-based
systems).

Also, some implementations, for example one of versions of DMDScript
doesn't have closures at all (there every internal returned function
will be strictly equal to the function return from the second call of
parent function - just like they joined objects, but in deed - this
implementation of ES doesn't have closures).

So closures in ECMAScript are:

1) from the theoretical viewpoint: *all* functions regardless
function's type;
2) from the practical viewpoint: functions which (a) have free
variables and (b) live longer than context in which they were created.

If you interesting in theory of closures (about the reasons for
creating the idea of closures, such as "Funarg" and so on): <URL:
"http://javascript.ru/blog/Dmitry-A.-Soshnikov/Tonkosti-ECMA-262-3.-
CHast-6.-Zamykaniya."> (online translator from Russian is needed).

/ds
 
G

Gregor Kofler

vunet meinte:
Thank you very much. Would you mind me asking for some brief
clarifications?


1. But can we call SomeGlobalVar.doIt() from outside if it is set
like:

SomeGlobalVar = (function () {
doIt : function(){}
})();

No.
But you can return an object with a callable property doIt():

SomeGlobalVar = (function () {
return { doIt : function(){} };
})();
2. and why keyword "var" is omitted? Is it needed at all?

Not necessarily. without "var" SomeGlobalVar will end up - as the name
suggests - in the global scope.

Gregor
 
G

Gregor Kofler

vunet meinte:
Thank you very much. Would you mind me asking for some brief
clarifications?


1. But can we call SomeGlobalVar.doIt() from outside if it is set
like:

SomeGlobalVar = (function () {
doIt : function(){}

You meant

var doIt = function() { ... };

- right?
 
V

vunet

No I meant
var globalObj = (function() {
        doIt : function(){
                alert("doIt executed");
        }

})();

Yes, sorry you are right. My syntax is incorrect.
 
G

Garrett Smith

kangax said:
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?
[...]

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

[snip]

<FAQENTRY/>

On the TODO list.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,079
Messages
2,570,575
Members
47,207
Latest member
HelenaCani

Latest Threads

Top