2

Can anyone please help me understand why the returned function is executed?

const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  setTimeout(function(i_local) {
    //The function below is just returned and not called using '()', so why is it executed? Why does the console.log works?
    return function() {
      console.log('The index of this number is: ' + i_local);
    }
  }(i), 3000);
}
AL-zami
  • 8,902
  • 15
  • 71
  • 130
Max
  • 82
  • 7
  • 1
    The returned function is passed to `setTimeout`. `setTimeout` will execute the passed function after the provided time. – Felix Kling Jan 14 '18 at 18:05

2 Answers2

4

The setTimeout function gets a function as an argument and executes it after X milliseconds.

In JavaScript, functions are like any other variable. You can pass them to other functions as an argument. The other functions are able to execute them later.

Like this:

function setNow(func){
    func()
}

setNow(function(){
    console.log('this will be executed.')
})

Also here, the function will be executed even if you do not call it directly using ().

In your example, your inner function returned, and now this is the function that setTimeout receives. It will be executed after X ms.

I recommend you to do it in a different way:

const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  setTimeout( (i_local=> {
      console.log('The index of this number is: ' + i_local);
  }).bind(this,i), 3000);
}

Learn more:

Aminadav Glickshtein
  • 23,232
  • 12
  • 77
  • 117
  • it actually worked for me as after have looked around the }(), timer} was not working and the version }(timer)() was working but caused a TypeError: setTimeout(...) is not a function – Carmine Tambascia May 11 '19 at 22:47
1

Because it's an IIFE

There is something called IIFE or immediately invoked function expression.They work in the following manner ( immediately invoked function expression )

(function(received argument){

     //some code here.......

})(passed argument)  //<-- here the function is invoked immediately after creation

The above function is invoked immediately when it is created. This type of declaration is used to keep variables private and to keep the global namespace clean.

it is equvalent to

function f(){} // we declare the function first

f() // and we invoked it later

The pattern in your code is used to create modules.

In your case :

setTimeout accept a function as it's first argument.And you have used an IIFE ,Which invokes immediately and returns a function.This returned function is used as argument in setTimeout.

AL-zami
  • 8,902
  • 15
  • 71
  • 130
  • visit here for elaborate discussion on iife https://stackoverflow.com/questions/27960682/what-is-this-code-construct-wrapping-the-parts-of-a-library-and-what-is-it-usefu/27960835#27960835 – AL-zami Jan 14 '18 at 18:27