1

Can someone help me understand this code? Why is the anonymous function inside brackets?

(function(food) {    
     if (food === "cookies") {        
         alert("More please");
     } else if (food === "cake") {
         alert("Yum yum");
     } 
 })("cookies");

If I reference the function in a variable like this and remove the brackets I can understand the function is being invoked passing in the cookies string.

 var foodFunc = function(food) {    
     if (food === "cookies") {        
         alert("More please");
     } else if (food === "cake") {
         alert("Yum yum");
     } 
 }

foodFunc("cookies");

Why would you use the first example? Why would you put the anonymous function in brackets?

Bomber
  • 10,195
  • 24
  • 90
  • 167
  • Its called as IIFE (Immediately Invoked Function Execution). Its used for functions that are required to be executed immediately but also are not required after that – Rajesh Oct 08 '16 at 09:13
  • Are you facing any issue that needs to be resolved? Please stick to the point. – Mini Bhati Oct 08 '16 at 09:14
  • Possible duplicate of [What is the (function() { } )() construct in JavaScript?](http://stackoverflow.com/questions/8228281/what-is-the-function-construct-in-javascript) – Rajesh Oct 08 '16 at 09:15

3 Answers3

0

The anonymous function has to be inside brackets, so it can be called right away. Writing function(){...}() wouldn't work. Using an anonymous function makes sense, if you only need it once, which likely is the case here.

Syntac
  • 1,687
  • 11
  • 10
0

The noticeable thing here is that:

    var food = function(food) {    
     if (food === "cookies") {        
         alert("More please");
     } else if (food === "cake") {
         alert("Yum yum");
     } 
}("cookies");

Doesn't need extra () too, and get foo to be the result of the call -undefined in this case, since the function doesn't return anything-.

That's because that is the native javascript syntax to declare a function.

However, when the javascript compiler finds a declaration like:

function foo(){
    return 'bar';
}

It transforms it to:

var foo = function(){ return 'bar'; };

(and also does some hoisting).

But if you would declare an IIFE like:

function(){
    //do something
}()

then the compiler can't assign it to a variable.

You could do:

function res(){
    console.log('res')
}()

And expect res to be declared as a function -to be appended to window- along with its execution. But that's usually not the desired behavior of an IIFE, so you're forced to add the extra () to tell the compiler to not save res as a function. Since, if you would want res to be both declared and called, you just should declare a res function and then call it. IIFE's aren't intended to declare a function, but, since the

function someFunc(){...}

Tells the compiler to declare someFunc as a var with the value of the defined function, you need that extra syntax to prevent IIFE's to declare variables.

Sergeon
  • 6,638
  • 2
  • 23
  • 43
0

There are many cases where you can use IIFEs. Following is one such case:

Adding Event Listener in loop:

Incorrect Output:

var els = document.getElementsByClassName("content");

for (var i = 0; i < els.length; i++) {
  els[i].addEventListener("click", function() {
    console.log(i);
  })
}
.content {
  height: 50px;
  width: 50px;
  border: 1px solid gray;
  line-height: 50px;
  text-align: center
}
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
<div class="content">4</div>
<div class="content">5</div>

Correct output:

var els = document.getElementsByClassName("content");

for (var i = 0; i < els.length; i++) {
  (function(i) {
    els[i].addEventListener("click", function() {
      console.log(i);
    })
  })(i)
}
.content {
  height: 50px;
  width: 50px;
  border: 1px solid gray;
  line-height: 50px;
  text-align: center
}
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
<div class="content">4</div>
<div class="content">5</div>

Also note, an IIFE is not accessible outside its scope.

(function notify(){
  console.log('hello');
})()

notify()

Reference:

Community
  • 1
  • 1
Rajesh
  • 24,354
  • 5
  • 48
  • 79