Search code examples
javascriptobject-literal

Extra parenthesis in object literal notation


I'm moving through the "Learning Javascript Design Patterns" book and I came across a peculiarity I can't quite wrap my head around. Looking at the following snippet:

var myNamespace = (function () {

  var myPrivateVar, myPrivateMethod;

  // A private counter variable
  myPrivateVar = 0;

  // A private function which logs any arguments
  myPrivateMethod = function( foo ) {
      console.log( foo );
  };

  return {

    // A public variable
    myPublicVar: "foo",

    // A public function utilizing privates
    myPublicFunction: function( bar ) {

      // Increment our private counter
      myPrivateVar++;

      // Call our private method using bar
      myPrivateMethod( bar );

    }
  };

})();

I get what's going on generally in the code. But I don't understand two excess pairs of parenthesis, the first being the pair that wraps function, and the second empty pair right before the empty semicolon. I would expect the formatting to look more like this:

var myNamespace = function () {

  var myPrivateVar, myPrivateMethod;

  // A private counter variable
  myPrivateVar = 0;

  // A private function which logs any arguments
  myPrivateMethod = function( foo ) {
      console.log( foo );
  };

  return {

    // A public variable
    myPublicVar: "foo",

    // A public function utilizing privates
    myPublicFunction: function( bar ) {

      // Increment our private counter
      myPrivateVar++;

      // Call our private method using bar
      myPrivateMethod( bar );

    }
  };

};

Needless to say, I tried compiling the code the way I thought it should look and it returned errors. Can anyone point me toward an explanation of why this works the way it does?


Solution

  • Sure. We can simplify the example so that the reason is obvious:

    This assigns a function to a variable:

    var func=function(){
      return 10;
    }
    

    This assigns the result of the function to another variable:

    var value=func();
    

    Now we'd like to call a function without having to name it, so we combine the above lines:

    var value=function(){
      return 10;
    }();
    

    But wait, this looks too much like defining a function - especially if the body is so long that we don't see the pair of parenthesis in the end. We want to indicate that we are calling a nameless function, so conventionally we write it like this:

    var value= (function(){
      return 10;
    })();
    

    Replace the part in the brackets with "func", and you'll see what I mean.