Forum Moderators: open
What does ()(); do?
I suppose an example for discussion might help, so I've thieved this one from Simon Willison's "A re-Introduction to Javascript":
var charsInBody = (function(elm) {
if (elm.nodeType == 3) { // TEXT_NODE
return elm.nodeValue.length;
}
var count = 0;
for (var i = 0, child; child = elm.childNodes[i]; i++) {
count += arguments.callee(child);
}
return count;
})(document.body);
If anybody could explain the above, or point me to a resource that would help me understand, I'd be very grateful. Afterall, searching ()(); on the web... isn't really effective.
function () {
alert('Fire');
}
doThis();
doThat();
With the anonymous function above, I can execute it immediately upon defining it by putting () after it:
function () {
alert('Fire');
}();
That, as written, will often work. But you don't know that the function is being executed until you reach the end of the function definition. Convention is to wrap the entire "expression" (aka, the function definition) in parenthesis so that it is clear that the result is going to be the result of calling the function and not the function itself.
For example, when doing:
var f = function () {
...
}();
var f = (function () {
...
})();
By convention, the first parenthesis is an indication that f is going to hold the result of the anonymous function that follows instead of holding the function definition.
Going back to your example, you have an anonymous function that takes one parameter. You are executing that function immediately, passing document.body as the parameter value, and you're assigning the return value of that function call to the variable charsInBody.
Using
(function () { ... })(); allows the enterprising JavaScript programmer to define variables which are present only within that little block of code, thus keeping the global namespace clean. It is nothing more than a syntactically verbose version of "let" from other programming languages (or let in JavaScript 1.7 [developer.mozilla.org]).
I was familiar with:
var f = function () {
...
}();
but I never realized that you could pass arguments to an anonymous function within its trailing bracket set. I played around and found out you can even nest ()(); (does it have a name? It reminds me of the O'rly Owl).
The following seems to work:
(function (thing2) {alert("Hello " + thing2)})((function (thing1) {return thing1;})("Fotiman"))
...but only if the semi-colon is omitted from at least the nested O'rly statement. Is the the semi-colon really necessary / part of the statement? What does a semi-colon mean?
If you're curious about how your example works, let's break it up a bit:
[pre](function (thing2) {
alert("Hello " + thing2);
})((function (thing1) {
return thing1;
})("Fotiman"));[/pre]
[pre]var return_thing1 = function (thing1) { return thing1; };
(function (thing2) {
alert("Hello " + thing2);
})(return_thing1("Fotiman"));[/pre]
[pre]var return_thing1 = function (thing1) { return thing1; };
var alert_hello = function (thing2) { alert("Hello " + thing2); };
alert_hello(return_thing1("Fotiman"));[/pre]
[pre]function return_thing1 (thing1) { return thing1; }
function alert_hello (thing2) { alert("Hello " + thing2); }
alert_hello(return_thing1("Fotiman"));[/pre]
It's nothing more than boring old function calls. Nothing particularly special is going on until you get into closures [en.wikipedia.org] (or the y combinator [en.wikipedia.org], but I digress).
Closure Example [pre]var closure = (function (say) {
return function (who) { alert(say+" "+who); };
})("Hello");
closure("Fotiman");
closure("World");[/pre]
As for semicolons, see JavaScript Syntax [en.wikipedia.org], or if you want to get into the really nitty-gritty details, see ECMA-262 [ecma-international.org]. But basically, they mark the end of statements. Yes, they're necessary; in some cases you can omit them (e.g., the end of a line), but you shouldn't.