Returns a function from an anonymous shell?

I'm trying to uncover code

for(var i = 0; i < 10; i++) { setTimeout((function(e) { return function() { console.log(e); } })(i), 1000) } 

from here http://bonsaiden.github.com/JavaScript-Garden/#function.closures

I understood this method:

 for(var i = 0; i < 10; i++) { (function(e) { setTimeout(function() { console.log(e); }, 1000); })(i); } 

Can someone help me explaining the first?

I will try to explain how I understand the first,

 first i is 0, setTimeout is called, self calling function "function(e)" is called with i=0, Im stuck!! what happens when this function returns a function? 
+4
source share
3 answers

"Could you check the updated question by indicating where im messed up?

OK, here is a long explanation. Remember that the first setTimeout() parameter must be a reference to the function that you want to execute after the specified delay. The simplest case is simply to name the function defined elsewhere:

 function someFunc() { console.log("In someFunc"); } setTimeout(someFunc, 100); 

Note that in someFunc there are no brackets when passed as the setTimeout parameter, because a link to this function is required. Contrast:

 setTimeout(someFunc(), 100); // won't work for someFunc() as defined above 

Using parenthese, it calls someFunc() and passes its return value to setTimeout . But my definition of someFunc() above does not explicitly return a value, so it implicitly returns undefined - it's like the expression setTimeout(undefined, 100) .

But this will work if you change someFunc() to return a function instead of returning undefined :

 function someFunc() { return function() { console.log("In the function returned from someFunc"); }; } 

So, now (finally) we get to the code from your question:

 setTimeout((function(e) { return function() { console.log(e); } })(i), 1000) 

Instead of referencing a function by name and calling it as someFunc(i) , it defines an anonymous function and immediately calls it as (function(e) {})(i) . This anonymous function returns another function, and this return function becomes the actual setTimeout() parameter. When time runs out, this is the return function to be executed. Since the returned (internal) function is defined in the scope of the (external) anonymous function, it has access to the parameter e .

+1
source

All that the first does is return a function that will be called after a timeout occurs.

The goal of this is to create a subrange for each iteration of the for loop so that the increment i not overridden by each iteration.

More explanation:

Let's divide this into two different parts:

 for(var i = 0; i < 10; i++) { setTimeout((function(e) { return function() { console.log(e); } })(i), 1000) } 

This is the first part:

 for(var i = 0; i < 10; i++) { setTimeout(function(){ console.log(i); //9-9 },1000); } 

Now, when you run this loop, you always get console.log (), which contains 9 instead of 0 to 9. This is because each setTimeout uses the same link to i .

If you end the setTimeout part from an anonymous function, it creates a scope for each iteration, allowing each setTimeout to have its own i value.

 for(var i = 0; i < 10; i++) { setTimeout((function(i) { return function() { console.log(i); // 0-9 } })(i), 1000) } 

The external function inside setTimeout is executed immediately with i from 0 for the first iteration, 1 for the second, etc. This function then returns a function, which is the function that setTimeout uses. A function is generated and returned for each iteration of the loop, using a different value for i .

+4
source

Both end with the same result: setTimeout is called with a function being called that writes a number from 0 to 9 on the console. Both use nested functions to get the current value of i in close, so you won’t finish registering 10 9.

The first code selects a function that returns the function that setTimeout will call. The second one changes the nesting order, so the closed call function calls setTimeout. The net effect is the same.

In addition to stylistic reasons and personal choice, I see no reason to choose one after another.

+2
source

All Articles