0

Was trying to figure out how to properly namespace my JavaScript in order to avoid conflicts with other libraries as well as global items. I was reviewing some code and noticed something I just do not understand when it comes to JavaScript. In all reality I don't even know how to ask the question so I will use some contrived code examples.

var varFuncTest = (function(){
         _funcTest = function(params){
       return "These are the params that were passed in: " + params;
     };
     return _funcTest;
})();

console.log(varFuncTest("params params params"));

OUTPUT: These are the params that were passed in: params params params

When I run this code it works as expected but that is only due to the fact that when I declared the variable I wrapped the function which is building and returning a specialized function in () and then added () right afterwards. When I log the function call I get the correct string printout.

Now when I remove that extra set of () from the end, because they looked unneeded to my untrained eyes, the log prints out the object type instead of the string.

var varFuncTest = (function(){
         _funcTest = function(params){
           return "These are the params that were passed in: " + params;
         };
         return _funcTest;
    });

    console.log(varFuncTest("params params params"));

OUTPUT: function()

What is going on here? Why is the second set of () needed? If this is a special function of the JavaScript language, what is it referred to and where can its documentation be found within the JavaScript API?

The code is identical minus the ending () on the 6th line of the first example. It is not a typo as it actually affects the execution within JavaScript. They both return a function object which is being assigned to the variable.

j08691
  • 204,283
  • 31
  • 260
  • 272
Schleichermann
  • 1,126
  • 3
  • 15
  • 26
  • 2
    Without the parentheses, you're returning a function. The parentheses call that returned function, so instead of returning a function, you're now returning the output of that function. – Blender Oct 31 '12 at 21:17
  • Addendum to Blender's excellent answer.... this might help you understand better why this pattern is used: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth – BLSully Oct 31 '12 at 21:29

2 Answers2

3

You use these parentheses all the time:

alert('foo');

Here, the parentheses call the function alert and pass in the argument 'foo'.

Take this function for example:

function test() {
    alert('foo');
}

Running test will only give you a reference to the function. test() will take that reference and call it.

In your specific example, this is precisely what is happening:

var varFuncTest = (function(){
     _funcTest = function(params){
       return "These are the params that were passed in: " + params;
     };
     return _funcTest;
})();

function() {...} returns another function (_funcTest). Those parentheses at the end call that returned function. If you omit them, varFuncTest will store a function. If you keep them, varFuncTest will store the output of that function instead.

Just to illustrate this, execute your second chunk of code and then run this:

varFuncTest();

You should get the same output as the first code chunk.

Blender
  • 289,723
  • 53
  • 439
  • 496
  • I would have answered quite the same. I would suggest a [Douglas Crockford video on function](http://www.youtube.com/watch?v=ya4UHuXNygM). It is lengthy but quite instructive, the best 60 minute a beginner would spend to learn javascript the right way. – Eineki Oct 31 '12 at 21:43
1

Javacript has the concept of an immediately invoked function. This is a function that is called as soon as it is defined. These need to be function expressions instead of function statements.

var a = function() {return "hi"}; // A reference to a function.. to call later.
alert(a()); // Call the function now.

vs

var a = (function() {return "hi"}()); // Call the function, return the value in one stop.
// a now has the result of the function.
alert(a);

Many of the answers given are true, or true-ish, but there is another aspect that none of them have mentioned.

When doing an assignment, such as

var a = (function() {}());

The outer-most level of parens are NOT needed by the compiler, but they server to inform the human reading the code that a immediately-invoked function is in place.

On the other hand, code like

(function() {}());  // One style
(function() {})();  // Another style

the parens are needed to force the compiler to read an expression, and thus a function-expression, rather than a function statement.

Using almost any other operator in front of the function keyword works, such as:

!function() {}();  // Another style

While that works, it isn't the normal 'idiom' to-to-say of Javascript.

TL-DR: The parens are there more the sake of humans than computers.

BTW: Please stick with the standard coding conventions. There are a lot of non-standard-but-legal things you can do. Don't. It confuses the person who comes after you.

Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74