Welcome to WebmasterWorld Guest from 23.22.207.70

Forum Moderators: open

Message Too Old, No Replies

what's this ()() stuff?

general question

     
9:29 pm on Sep 21, 2009 (gmt 0)

New User

5+ Year Member

joined:Sept 21, 2009
posts: 8
votes: 0


So... I am a novice Javascripter, but I have come to the point where I am learning about custom objects and scope. And occasionally I run into code with this: ()();

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.

9:32 pm on Sept 21, 2009 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:June 27, 2003
posts:835
votes: 0


I'm going to resist the obvious joke here. Even the more obvious joke about putting decimal points inside.

*leaves thread untouched by debauchery*

12:47 am on Sept 22, 2009 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member fotiman is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Oct 17, 2005
posts:4986
votes: 12


Lets take an even smaller example:


function () {
alert('Fire');
}

That is an anonymous function. I can't call that function because it doesn't have a name. And how do we execute a function? We put () after the function. For example:

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

If I look at the first line, I might think that f is going to hold a function definition. However, if I do this:

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.

1:19 am on Sept 22, 2009 (gmt 0)

Junior Member

10+ Year Member

joined:Jan 28, 2006
posts:96
votes: 0


The entire point of this contraption, by the way, is because JavaScript only has two variable scopes: global, and function.

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]).
5:18 pm on Sept 22, 2009 (gmt 0)

New User

5+ Year Member

joined:Sept 21, 2009
posts:8
votes: 0


Thank you Fotiman! (and pinterface for your comment).

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?

2:22 am on Sept 23, 2009 (gmt 0)

Junior Member

10+ Year Member

joined:Jan 28, 2006
posts:96
votes: 0


Yes, you can nest anonymous functions (also known by the overused Greek letter, lambda). So far as I know there's no special name for nesting them, because there's nothing special about it.

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]

is functionally equivalent to:
[pre]var return_thing1 = function (thing1) { return thing1; };
(function (thing2) {
alert("Hello " + thing2);
})(return_thing1("Fotiman"));[/pre]

is functionally equivalent to:
[pre]var return_thing1 = function (thing1) { return thing1; };
var alert_hello = function (thing2) { alert("Hello " + thing2); };
alert_hello(return_thing1("Fotiman"));[/pre]

is functionally equivalent to:
[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.

3:55 am on Sept 23, 2009 (gmt 0)

New User

5+ Year Member

joined:Sept 21, 2009
posts:8
votes: 0


Thanks pinterface.

I realize that the nesting of anonymous functions is a moot point -- it was more the semicolon that was puzzling me. So I'll have a look at the ECMA.

(And the name ORLY statement still amuses me... but I am a pretty easily amused kind of person. :P)

10:09 am on Sept 25, 2009 (gmt 0)

Administrator

WebmasterWorld Administrator coopster is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:July 31, 2003
posts:12537
votes: 0


I'll throw in another vote for using semicolons to mark end of statements. If you ever intend to use a compression utility on your file you'll need those semicolons.
5:46 pm on Sept 25, 2009 (gmt 0)

Senior Member

WebmasterWorld Senior Member whoisgregg is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Dec 9, 2003
posts:3416
votes: 0


As a PHP & Javascript programmer, I always use semicolons. It breaks PHP if they're missing, so if you have plans to expand into that language you should get used to always including them.
 

Join The Conversation

Moderators and Top Contributors

Hot Threads This Week

Featured Threads

Free SEO Tools

Hire Expert Members