10

Possible Duplicate:
How does the (function() {})() construct work and why do people use it?

Why do the modern JavaScript files use constructs like:

(function () {
   // some real code
 }());

I.e. I understand that an anonymous function is being created and then called immediately, with no parameters passed... But why do it this way and not just call some real code? And what is the outer pair of round brackets for?

In particular I'm staring at the file js/start.js at Github:

(function() {
    "use strict";

    wooga.castle.GRID_UNIT = 48;
    wooga.castle.IMAGES_BASE_URL = "images/entities/";

    (function () {
        var style = document.createElement('div').style,
            prefix;
        var candidates = {
            webkit: 'webkitTransform',
            moz:    'MozTransform', // 'M' is uppercased
            ms:     'msTransform',
            o:      'oTransform',
            '':     'transform'
        };
        for (var prefix in candidates) {
            var candidate = candidates[prefix];
            if ('undefined' !== typeof style[candidate]) {
                wooga.castle.prefix = prefix;
                wooga.castle.prefixedTransform = candidate;
                break;
            }
        }
    }());

    // XXX why the 2 wrapped "function"s here? XXX

    wooga.castle.isNativeWrapper = function() {
        var result = !wooga.castle.capabilities.desktop && !wooga.castle.capabilities.android && (! /Safari/.test(navigator.userAgent));
        wooga.castle.isNativeWrapper = function () {
            return result;
        };
        return result;
    };
}());

With my basic JavaScript and jQuery skills I understand the single commands listed above, but I don't get why are they wrapped inside of several functions. Can't we just call:

    "use strict";

    wooga.castle.GRID_UNIT = 48;
    wooga.castle.IMAGES_BASE_URL = "images/entities/";
    var style = document.createElement('div').style,
        prefix;
    var candidates = {
        webkit: 'webkitTransform',
        moz:    'MozTransform', // 'M' is uppercased
        ms:     'msTransform',
        o:      'oTransform',
        '':     'transform'
    };
    for (var prefix in candidates) {
        var candidate = candidates[prefix];
        if ('undefined' !== typeof style[candidate]) {
            wooga.castle.prefix = prefix;
            wooga.castle.prefixedTransform = candidate;
            break;
        }
    }

    wooga.castle.isNativeWrapper = !wooga.castle.capabilities.desktop && !wooga.castle.capabilities.android && (! /Safari/.test(navigator.userAgent));
Community
  • 1
  • 1
Alexander Farber
  • 21,519
  • 75
  • 241
  • 416
  • I've seen `((function() {})())` but not `(function() {}())`. – kevin628 Jun 26 '12 at 14:48
  • @kevin628: I've never seen `((function() {})())`. That's way too many `()`s. The other way is: `(function(){})()` – gen_Eric Jun 26 '12 at 14:49
  • @Rocket Looks like they are the same thing, at least in Chrome. One just has fewer mind-bending `()`s. I learned something new today. – kevin628 Jun 26 '12 at 14:51

3 Answers3

11

This is done so the code inside doesn't interfere with variables in the global scope.

For example:

var myLibrary = {};
var _privateVar = [];

Now, both of these are global. But, I don't want that. So, if I make a function, I can make a new scope.

(function(){
    window.myLibrary = {}; // global
    var _privateVar = []; // private
}());
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
3

It's called a closure, it's designed to encapsulate code so that variables and functions are not declared in the global scope, preventing conflicts.

michael
  • 4,427
  • 6
  • 38
  • 57
2

This is done to prevent "Pollution of the global scope". By surrounding the code with an anonymous function the variables exist only in the scope of the function thus preventing possible conflicts in the global namespace.

The outer brackets are needed because function(){} itself is a declaration and you need to turn it into an expression by adding either (...) or and ! in front of it in order to execute it.

Christoph
  • 50,121
  • 21
  • 99
  • 128