Why is it not recommended to create functions inside a loop in JavaScript?

I am an absolute beginner and I just read this in JavaScript: Good details.

The scope chapter says: β€œIt's important to understand that an internal function has access to the actual variables of the external functions, not copies, to avoid the following problem.” And then the following two examples look like this:

// FIFTH EXAMPLE

var add_the_handlers = function (nodes) { var i; for (i = 0; i < nodes.length; i += 1) { nodes[i].onclick = function (e) { alert(i); }; } }; 

// END BAD EXAMPLE

 var add_the_handlers = function (nodes) { var helper = function (i) { return function (e) { alert(i); }; }; var i; for (i = 0; i < nodes.length; i += 1) { modes[i].onclick = helper(i); } }; 

According to the author, the second example is better, because it does not use a loop inside a function, otherwise it can be wastefully computational. But I am in loss and do not know what to do with them. How can I bring my theory into a real application? Can someone illustrate these two examples, combine HTML?

+7
javascript html
source share
5 answers

The problem is closing. Internal functions have access to the variable i defined outside of these functions. After completing all iterations of the loop, the variable i will contain the value nodes.length . Therefore, when you click on nodes[0] , the message nodes.length will appear in the message, which you do not expect. (You would expect a warning to say 0 ) The same thing can be done when you click nodes[1] , nodes[2] , etc. A warning for all of them will say nodes.length .

+6
source share

You can check this with HTML: https://jsfiddle.net/vdrr4519/ .

Items

'multifunc' is introduced with an example with many singlefunc functions - with one. See, We take all the elements with the class and pass their functions.

 multifunc(document.querySelectorAll('.multifunc')); 

The function starts the 'for' loop and adds a 'click' event listener. Therefore, the element must warn its index when pressed (starting at 0). But in the example with many functions, the wrong value is created (due to closure, other answers also indicate a problem).

I think I should also say that it does not release functions with one function / mutliple - this is a matter of working with closure. You see, I can implement a working example with many closures: https://jsfiddle.net/pr7gqtdr/1/ . I do basically the same thing as in the handler with one function, but each time I call the new function "helper":

  nodes[i].onclick = function (i) { return function (e) { alert(i); }; }(i); 

See, this (i) at the end is an immediate function call, so onclick gets the function with the variable i set in the close.

But, the options of one function are slightly better, because, in my opinion, this is more efficient memory. Functions are objects. If you create many of them, you take more memory in general. Therefore, choosing from them, I stick to the option function "handler".

+1
source share

A bad example creates many event handlers; One for the event. In a good example, create one event handler and assign it to all events.

With a bad example, you have created many separate functions, not just one. This can be a lot of extra overhead and a lot of potential coverage problems. These include problems with closing, such as an event that only fires for the last element in the loop.

In addition, a good example allows you to more easily unsubscribe from events, because you have access to the original function pointer.

A good example is also easier to read and understand. The loop is only used to create elements and bind their events; These events are handled elsewhere.

0
source share

As Soviut mentions, you are creating many event handlers in a bad example. In addition, it is important to note that the functions of bad examples belong to the same variable i , which means that all of them will have the last value nodes.length when they are executed.

This is because a closure is created. For more information, see Closures .

0
source share

First, in a bad example, a function is created for each event handler; a loop creates several function objects. While in the second example, one function is created and referenced from within the loop. This way you save a lot of memory.

Secondly, in a bad example, when the value of "i" is started, the function does not save the value, and when it is executed, it always returns the last value of "i". In a good example, however, since "i" is passed to the function, this value is stored as the lexical environment of the function, and when it is called, it will return the correct value.

Thirdly, as @Gary Hayes mentioned, we could also use this function elsewhere. Therefore, it is better to keep it independent of the cycle.

0
source share

All Articles