About (function(){})()

V

vunet

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
 
R

RobG

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

The suggestion on the jQuery documentation page doesn’t 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 doesn’t 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.

It’s 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 doesn’t.

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
you’ll work together to avoid other issues (e.g. overwriting
listeners) and can therefore easily determine a strategy for avoiding
name conflicts anyway. Otherwise, don’t 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, it’s useful for creating public and private
variables using functions with closures and to execute code that, once
run, doesn’t 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
library’s functions because your library’s functions may mask them.

The maintenance issue shouldn’t be underestimated - any time you
introduce more complex code patterns, you run the risk that some
future coder won’t understand it and stuff the whole thing up. It’s
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 it’s worth. It’s 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.

There’s 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! :)
 
D

David Mark

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

Seen long before jQuery.
(function() {
  var global = this;
  // ...

})();

Actually, that looks like my library.
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.
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.
are the advantages?

For one, you can have protected members, which you cannot do with an
object literal alone.

[snip]
 
V

vunet

The suggestion on the jQuery documentation page doesn’t 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 doesn’t 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.




A more robust version is:

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

but it may not matter very often.


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.

It’s 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.


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



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 doesn’t.

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.


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
you’ll work together to avoid other issues (e.g. overwriting
listeners) and can therefore easily determine a strategy for avoiding
name conflicts anyway.  Otherwise, don’t 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.


See above.  Also, it’s useful for creating public and private
variables using functions with closures and to execute code that, once
run, doesn’t 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
library’s functions because your library’s functions may mask them.

The maintenance issue shouldn’t be underestimated - any time you
introduce more complex code patterns, you run the risk that some
future coder won’t understand it and stuff the whole thing up.  It’s
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 it’s worth.   It’s 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.

There’s 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.


Clear!  :)

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.
 
H

hj

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.
 
R

RobG

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
object:property 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 don’t 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.
 
R

Rik Wasmus

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
object:property 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...
 

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

Staff online

Members online

Forum statistics

Threads
474,137
Messages
2,570,802
Members
47,349
Latest member
eixataze

Latest Threads

Top