homepage Welcome to WebmasterWorld Guest from 54.226.21.57
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
Forum Library, Charter, Moderator: open

JavaScript and AJAX Forum

    
what's this ()() stuff?
general question
volkes

5+ Year Member



 
Msg#: 3993104 posted 9:29 pm on Sep 21, 2009 (gmt 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.

 

esllou

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 3993104 posted 9:32 pm on Sep 21, 2009 (gmt 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*

Fotiman

WebmasterWorld Senior Member fotiman us a WebmasterWorld Top Contributor of All Time 5+ Year Member



 
Msg#: 3993104 posted 12:47 am on Sep 22, 2009 (gmt 0)

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.

pinterface

5+ Year Member



 
Msg#: 3993104 posted 1:19 am on Sep 22, 2009 (gmt 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]).

volkes

5+ Year Member



 
Msg#: 3993104 posted 5:18 pm on Sep 22, 2009 (gmt 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?

pinterface

5+ Year Member



 
Msg#: 3993104 posted 2:22 am on Sep 23, 2009 (gmt 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.

volkes

5+ Year Member



 
Msg#: 3993104 posted 3:55 am on Sep 23, 2009 (gmt 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)

coopster

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



 
Msg#: 3993104 posted 10:09 am on Sep 25, 2009 (gmt 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.

whoisgregg

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



 
Msg#: 3993104 posted 5:46 pm on Sep 25, 2009 (gmt 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.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved