2

The Google Analytics tracking code looks like this:

(function() {
code
  })();

What's the technique they are using with those brackets - (stuff)() - called? What does it do?

I put the Google Analytics code before the closing head tag on my page and then put an if statement around it like this (I include a Jquery cookie plugin further up):

<script type="application/javascript">
if ($.cookie('allowcookies') == 'yes') {
analytics code
}
</script>

It didn't run until I used the same technique around my code:

(function() {if ($.cookie('allowcookies') == 'yes') {

analytics code
}
})();

Why did it not run before I did that? Why did it run after?

paulmorriss
  • 2,579
  • 25
  • 30
  • http://stackoverflow.com/questions/939386/immediate-function-invocation-syntax – Ja͢ck Sep 04 '12 at 09:18
  • What was the condition that you used? – Ja͢ck Sep 04 '12 at 09:20
  • perhaps it's better to show the full code that you had before. – Ja͢ck Sep 04 '12 at 09:35
  • 1
    seems like a fluke, it's very likely that jQuery didn't fully load the first time and making the change didn't make a difference except that jQuery was then cached by the browser. – Ja͢ck Sep 04 '12 at 12:01
  • Agree with @Jack, I'd say to put your anonymous function inside a `$(document).ready(function(){ ... });` Also, your code is missing a closing parenthesis after your last bracket. – Victor Schröder Sep 04 '12 at 21:05
  • @VictorSchröder When I put it in $(document).ready... it ran, but the Google analytics script didn't run. I think because Google puts its code in the head tag it needs to run while the page is loading. – paulmorriss Sep 05 '12 at 08:06
  • Can you show us your URL? Are you sure that the jQuery cookie extension is loading? Are you creating the `_gaq` var in global scope? – Victor Schröder Sep 05 '12 at 13:00
  • http://wycliffe.org.uk/cookietest.html. Other code on the same page that checks the cookie has been working before I added this stuff, so I'm pretty sure the extension is loading. Yes, I'm loading it in global scope now that I've put the ()() stuff around it. – paulmorriss Sep 05 '12 at 13:10
  • I checked your page. The code is working fine. The problem is that your code only checks the cookie presence on page load. You have to check it on the checkbox change as well, and then load GoogleAnalytics. – Victor Schröder Sep 05 '12 at 13:47
  • I know the code is working fine, my question was why it didn't work when I didn't put ()() stuff around it! Thanks for spotting that I didn't load analytics on checkbox change. Now that it's working I'm not that bothered about why it didn't work before, so you don't need to help any further, thanks. – paulmorriss Sep 05 '12 at 13:53
  • When I analysed your code in a console, I realised that the problem was the cookie's existence. The check was returning true only when the cookie was already there on page load, which is not the case for a new visitor. When you click the checkbox, the cookie is written, but there was no recheck. Personaly, I'd not use a self executed anonymous function (seaf) to do that, because you probably will have to call it again later, and there's no way to call again a seaf, it only runs once, at page load (if outside another function, of course). – Victor Schröder Sep 05 '12 at 15:09

3 Answers3

8
(function() {
   /* code */
}()); 

It's commonly known as «self executed anonymous function (¹)» (o «immediate function invocation») and its main use is to avoid the creation of variables into the global (or in the outer) scope.

It's also used as shortcut when you want to create a function to execute just once, without the need to first define the function with its own identifier and then soon make the function call.

It may be eventually used inside a scope and then it may create a closure if the outer context (or other references) are binded through parameters passing, e.g.

/* outer scope */  
(function(outerscope) {

   element.onsomeevent = function() {
       /* do something with outerscope */
   };

}(this));

Another practical use I make with this expression is when I need to create a function to be soon executed inside a constructor function when it is called with new keyword (instead of an explicit call to some init method).


(¹) — as stated on book "Mantainable Javascript" by Nicholas Zakas (O'Reilly, ISBN 978-1-449-32768-2) page 44, the suggested expression is (function() {}()), with nested parens (even if (function() {})() will work anyway)

[...]To make it obvious that immediate function invocation is taking place, put paretheses around the function[...]

See also Immediate function invocation syntax

Community
  • 1
  • 1
Fabrizio Calderan
  • 120,726
  • 26
  • 164
  • 177
3

The "function(){code}" part only creates a function, the () at the end call the created function. You could rewrite

(function() {
code
  })();

As

var x = function() {code};
x();
rx80
  • 156
  • 4
1

It's just a select calling function. The () at the end causes it to be called automatically.

It's used like this to isolate local variables that are relevant only to your code from the global scope.

For example:

(function() {

   var x = 5;
   window.y = 6;

})();

x is available only in the scope of the function, y is globally available through the window.

As to it not running, I'd hazard that's down to the conditional you supplied.

Lloyd
  • 29,197
  • 4
  • 84
  • 98