HighDots Forums  

About (function(){})()

Javascript JavaScript language (comp.lang.javascript)


Discuss About (function(){})() in the Javascript forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
vunet
 
Posts: n/a

Default About (function(){})() - 10-29-2008 , 09:46 AM






It has been widely used nowadays to wrap JavaScript libraries, as seen
in JQuery.

(function() {
var global = this;
// ...
})();

The advantage, as I learned, is the isolation from other global
variables. But how? What other advantages does this wrapper have. For
example, I have my library as:

var myLib = {
go : function(){
alert('Hah')
},
arr : new Array()
}

How would I write myLib in (function(){})() format? Do I need to? What
are the advantages?
Please clear for me if you can.
Thanks

Reply With Quote
  #2  
Old   
RobG
 
Posts: n/a

Default Re: About (function(){})() - 10-29-2008 , 08:32 PM






On Oct 29, 11:46 pm, vunet <vunet... (AT) gmail (DOT) com> wrote:
Quote:
It has been widely used nowadays to wrap JavaScript libraries, as seen
in JQuery.
The suggestion on the jQuery documentation page doesnt wrap jQuery,
it wraps your code and passes the jQuery object to it. It is based on
the idea that there is a major conflict between a number of libraries
as a result of their use of $ as the name of a function that is
fundamental to their operation. jQuery creates a global $ varaible
that is assigned a reference to the jQuery object so programmers can
write $() instead of jQuery().

One strategy suggested is to use:

(function($){ /* code using $ */})(jQuery);

However, it doesnt fix the conflict, it just makes it manageable. A
consequence is that it makes it more difficult (though not impossible)
to use the $ function of other libraries from inside the anonymous
function. Given the importance of $ to those libraries (and its
frequent use by them internally as a global variable) it might not be
a good strategy.

Quote:
(function() {
var global = this;
A more robust version is:

var global = (function(){return this})();


but it may not matter very often.


Quote:
// ...

})();

The advantage, as I learned, is the isolation from other global
variables. But how?
You are only isolated to the extent that variables that would have
been declared as global are now local to the anonymous function. The
conflicts are still there, just that the local variables mask them.
Undeclared variables (bad practice but it happens) get no isolation
and may behave quite differently to what you expect (or not, depending
on your knowledge of ECMAScript).

You can still create global variables (global.varName = ...), but the
idea is to keep it all within the same scope.

Its a double-edged sword though - you may *want* to use the masked
variables (you can get at them using global.varName or similar) but
because the code is executed immediately, they may not be available
yet. If you have conflicts with names, you may not be ablet to
control the order scripts are loaded in either.


Quote:
What other advantages does this wrapper have.
It makes conflicts manageable and can be used to create public and
private variables.


Quote:
For example, I have my library as:

var myLib = {
go : function(){
alert('Hah')
},
arr : new Array()

}

How would I write myLib in (function(){})() format?
Put your library and all the code that you are going to execute inside
an anonymous function:

(function() {
// declare myLib
var myLib = {...};

// now use it.
myLib.go(...);
// and so on
})();

There are other approaches, e.g. put your code in the same file as the
library and ensure it loads first. It would be good if HTML script
elements allowed:

<script src=myLib.js> code that uses myLib</script>

But it doesnt.

You need to dynamically add any listeners that will call functions in
your library and keep references using closures - trying to call
myLib.go() from an inline listener will error. Adding listeners
dynamically leaves you open to memory leaks in IE if not done
properly.


Quote:
Do I need to?
It might be worth considering if you have others adding code that you
have no control over to pages that your code is to be run in. But
naming conflicts are only one issue there, you need to work out how
youll work together to avoid other issues (e.g. overwriting
listeners) and can therefore easily determine a strategy for avoiding
name conflicts anyway. Otherwise, dont bother. Patterns for public
and private variables should be used on their own merits, not in the
belief that they are a magic bullet that solves naming conflicts.

Quote:
What are the advantages?
See above. Also, its useful for creating public and private
variables using functions with closures and to execute code that, once
run, doesnt need to do anything further. It might also help to ask
about the disadvantages. :-)

Depending on how you implement it, it becomes more complex to write
and maintain, e.g. in-line handlers may not be able to call your
functions so they have to be added dynamically, probably using
window.onload or similar, and keep references using closures. It may
use a lot more memory but not necessarily.

You may still get conflicts with global variables from another
librarys functions because your librarys functions may mask them.

The maintenance issue shouldnt be underestimated - any time you
introduce more complex code patterns, you run the risk that some
future coder wont understand it and stuff the whole thing up. Its
usually OK in a library function that *should* be maintained by
someone who knows what they are doing, but to use it as a general
pattern in a page that will change frequently by persons unknown may
be more trouble than its worth. Its rare for a good programmer to
last on maintenance tasks for very long - either they are put to more
profitable uses when their talent is noticed or they lose interest and
go elsewhere.

Theres a lot to be said for the ancient keep it simple,
stupid (KISS) principle. As always, you have to weigh up the pros
and cons.

Quote:
Please clear for me if you can.
Clear! :-)


--
Rob


Reply With Quote
  #3  
Old   
David Mark
 
Posts: n/a

Default Re: About (function(){})() - 10-29-2008 , 08:43 PM



On Oct 29, 9:46*am, vunet <vunet... (AT) gmail (DOT) com> wrote:
Quote:
It has been widely used nowadays to wrap JavaScript libraries, as seen
in JQuery.
Seen long before jQuery.

Quote:
(function() {
* var global = this;
* // ...

})();
Actually, that looks like my library.

Quote:
The advantage, as I learned, is the isolation from other global
variables. But how? What other advantages does this wrapper have. For
example, I have my library as:
How what? As for other advantages, "minifiers" can be more aggressive
with this pattern.

Quote:
var myLib = {
* go : function(){
* * alert('Hah')
* },
* arr : new Array()

}

How would I write myLib in (function(){})() format? Do I need to? What
It is hard to say what you need to do. The sample above doesn't
indicate what you are trying to do.

Quote:
are the advantages?
For one, you can have protected members, which you cannot do with an
object literal alone.

[snip]


Reply With Quote
  #4  
Old   
vunet
 
Posts: n/a

Default Re: About (function(){})() - 10-30-2008 , 09:55 AM



On Oct 29, 8:32*pm, RobG <rg... (AT) iinet (DOT) net.au> wrote:
Quote:
On Oct 29, 11:46 pm, vunet <vunet... (AT) gmail (DOT) com> wrote:

It has been widely used nowadays to wrap JavaScript libraries, as seen
in JQuery.

The suggestion on the jQuery documentation page doesnt wrap jQuery,
it wraps your code and passes the jQuery object to it. *It is based on
the idea that there is a major conflict between a number of libraries
as a result of their use of $ as the name of a function that is
fundamental to their operation. *jQuery creates a global $ varaible
that is assigned a reference to the jQuery object so programmers can
write $() instead of jQuery().

One strategy suggested is to use:

* (function($){ /* code using $ */})(jQuery);

However, it doesnt fix the conflict, it just makes it manageable. *A
consequence is that it makes it more difficult (though not impossible)
to use the $ function of other libraries from inside the anonymous
function. *Given the importance of $ to those libraries (and its
frequent use by them internally as a global variable) it might not be
a good strategy.



(function() {
* var global = this;

A more robust version is:

* var global = (function(){return this})();

but it may not matter very often.

* // ...

})();

The advantage, as I learned, is the isolation from other global
variables. But how?

You are only isolated to the extent that variables that would have
been declared as global are now local to the anonymous function. *The
conflicts are still there, just that the local variables mask them.
Undeclared variables (bad practice but it happens) get no isolation
and may behave quite differently to what you expect (or not, depending
on your knowledge of ECMAScript).

You can still create global variables (global.varName = ...), but the
idea is to keep it all within the same scope.

Its a double-edged sword though - you may *want* to use the masked
variables (you can get at them using global.varName or similar) but
because the code is executed immediately, they may not be available
yet. *If you have conflicts with names, you may not be ablet to
control the order scripts are loaded in either.

What other advantages does this wrapper have.

It makes conflicts manageable and can be used to create public and
private variables.

For example, I have my library as:

var myLib = {
* go : function(){
* * alert('Hah')
* },
* arr : new Array()

}

How would I write myLib in (function(){})() format?

Put your library and all the code that you are going to execute inside
an anonymous function:

(function() {
* // declare myLib
* var myLib = {...};

* // now use it.
* myLib.go(...);
* // and so on

})();

There are other approaches, e.g. put your code in the same file as the
library and ensure it loads first. *It would be good if HTML script
elements allowed:

* <script src=myLib.js> code that uses myLib</script

But it doesnt.

You need to dynamically add any listeners that will call functions in
your library and keep references using closures - trying to call
myLib.go() from an inline listener will error. *Adding listeners
dynamically leaves you open to memory leaks in IE if not done
properly.

Do I need to?

It might be worth considering if you have others adding code that you
have no control over to pages that your code is to be run in. *But
naming conflicts are only one issue there, you need to work out how
youll work together to avoid other issues (e.g. overwriting
listeners) and can therefore easily determine a strategy for avoiding
name conflicts anyway. *Otherwise, dont bother. *Patterns for public
and private variables should be used on their own merits, not in the
belief that they are a magic bullet that solves naming conflicts.

What are the advantages?

See above. *Also, its useful for creating public and private
variables using functions with closures and to execute code that, once
run, doesnt need to do anything further. *It might also help to ask
about the disadvantages. *:-)

Depending on how you implement it, it becomes more complex to write
and maintain, e.g. in-line handlers may not be able to call your
functions so they have to be added dynamically, probably using
window.onload or similar, and keep references using closures. *It may
use a lot more memory but not necessarily.

You may still get conflicts with global variables from another
librarys functions because your librarys functions may mask them.

The maintenance issue shouldnt be underestimated - any time you
introduce more complex code patterns, you run the risk that some
future coder wont understand it and stuff the whole thing up. *Its
usually OK in a library function that *should* be maintained by
someone who knows what they are doing, but to use it as a general
pattern in a page that will change frequently by persons unknown may
be more trouble than its worth. * Its rare for a good programmer to
last on maintenance tasks for very long - either they are put to more
profitable uses when their talent is noticed or they lose interest and
go elsewhere.

Theres a lot to be said for the ancient keep it simple,
stupid (KISS) principle. *As always, you have to weigh up the pros
and cons.

Please clear for me if you can.

Clear! *:-)

--
Rob
Thank you for very descriptive answer. Can I possible clear out about
what happens when this is excecuted:

(function() {
// declare myLib
var myLib = {...};

// now use it.
myLib.go(...);
// and so on

})();

The code is executed on JS run-time and is hidden to any other
libraries or variables because of the wrapper function. But at the
same time that code cannot be accessed from outside if I have onClick
handler to run one of the functions inside like onClick="myLib.go()".
Is this more "robust" (as you say) because it is global:
var global = (function(){return this})();
Thank you very much.


Reply With Quote
  #5  
Old   
hj
 
Posts: n/a

Default Re: About (function(){})() - 10-30-2008 , 12:47 PM



On Oct 29, 6:46 am, vunet <vunet... (AT) gmail (DOT) com> wrote:
Quote:
It has been widely used nowadays to wrap JavaScript libraries, as seen
in JQuery.

(function() {
var global = this;
// ...

})();

The advantage, as I learned, is the isolation from other global
variables. But how? What other advantages does this wrapper have. For
example, I have my library as:
Here's a concrete example: Imagine that you have some functions to
declare, *and*
some code that you want to be executed, e.g.:


function x() {
// Do something
}
function y(a) {
// Do something else
}
function untilSometime() {
x();
if ((now.getTime() + 1000) < (new Date().getTime())) {
y();
} else {
clearInterval(ihandle);
}
}
var now = new Date;
var ihandle = setInterval(untilSometime,100);


The result is that "x", "y", "untilSometime", "now", and "ihandle" are
all
global properties. There's a possibility that any of them have
overwritten
pre-existing properties with the same names, as well as the
possibility that
they'll be overwritten by code later in the document. Wrapping the
whole
thing in an immediately executed function expression makes all those
local
to that function, and avoids both those problems; and produces the
desired
effect without creating -any- global properties.

--

hj


Reply With Quote
  #6  
Old   
RobG
 
Posts: n/a

Default Re: About (function(){})() - 10-31-2008 , 02:18 AM



On Oct 30, 11:55 pm, vunet <vunet... (AT) gmail (DOT) com> wrote:
[...]
Quote:
Thank you for very descriptive answer. Can I possible clear out about
what happens when this is excecuted:

(function() {
// declare myLib
var myLib = {...};

// now use it.
myLib.go(...);
// and so on

})();

The code is executed on JS run-time and is hidden to any other
libraries or variables because of the wrapper function. But at the
same time that code cannot be accessed from outside if I have onClick
handler to run one of the functions inside like onClick="myLib.go()".
Is this more "robust" (as you say) because it is global:
var global = (function(){return this})();
No. I suggested it because that method of getting a reference to the
global object can be used anywhere, you dont have to run it as global
code.

Using an anonymous function wrapper around your library is not
necessarily more robust (depending on what you think that means), in
fact it can make life more difficult as you have to add listeners
dynamically, which introduces a whole new set of issues. If it is
purely to avoid naming clashes, an good technique is to use a prefix
for your functions, e.g.

function vU_go() { ... }
function vU_stop() { ... }

And so on. That method provides about the same protection as the
objectroperty method of:

var vU = {
go: function() {...}
stop: function() {...}
}

If you can get away with simple listeners like:

<input type=button onclick=vU_go()>

then do it. Inline listeners are pretty much bullet-proof and are
available to act as soon as the HTML is displayed. Users dont have
to wait, adding multiple listeners is easy and you have some control
over the order in which they fire.

There are cases where dynamic handlers are better, but for the general
web, inline is the way to go if you can keep the listeners simple.

Event delegation can be used to greatly reduce the number of listeners
in a page, e.g. rather then putting a listener on every element in a
menu structure, put a single listener on a common parent and catch
events as they bubble. Some take this to the extreme with a single
listener per event type on the body element, but that is probably
going too far.


--
Rob


Reply With Quote
  #7  
Old   
Rik Wasmus
 
Posts: n/a

Default Re: About (function(){})() - 11-01-2008 , 12:17 AM



On Fri, 31 Oct 2008 07:18:02 +0100, RobG <rgqld (AT) iinet (DOT) net.au> wrote:

Quote:
On Oct 30, 11:55 pm, vunet <vunet... (AT) gmail (DOT) com> wrote:
[...]
Thank you for very descriptive answer. Can I possible clear out about
what happens when this is excecuted:

(function() {
// declare myLib
var myLib = {...};

// now use it.
myLib.go(...);
// and so on

})();

The code is executed on JS run-time and is hidden to any other
libraries or variables because of the wrapper function. But at the
same time that code cannot be accessed from outside if I have onClick
handler to run one of the functions inside like onClick="myLib.go()".
Is this more "robust" (as you say) because it is global:
var global = (function(){return this})();

No. I suggested it because that method of getting a reference to the
global object can be used anywhere, you don’t have to run it as global
code.

Using an anonymous function wrapper around your library is not
necessarily more robust (depending on what you think that means), in
fact it can make life more difficult as you have to add listeners
dynamically, which introduces a whole new set of issues. If it is
purely to avoid naming clashes, an good technique is to use a prefix
for your functions, e.g.

function vU_go() { ... }
function vU_stop() { ... }

And so on. That method provides about the same protection as the
objectroperty method of:

var vU = {
go: function() {...}
stop: function() {...}
}

If you can get away with simple listeners like:

input type=”button” onclick=”vU_go()”
Hmmm, and prevent 'smart' applications from converting your carefully used
'"'s to '”'....

(=94 => decimal 148 in the windows-1252/quoted-printable source)

/prays to a random deity for this post to make sense when sent, I don't
even trust my nntp client all that much...
--
Rik


Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.