1

JSHint is complaining at me because I'm looping over an object using for(o in ...), then using a o.somearray.forEach(function(){...}); inside. It's saying to not create functions within loops, but does it even matter in this case? It looks a bit nicer since there's less lines and it looks (slightly) better, but are there any major implications from it?

Is it any better to use a normal for-loop and iterate over the array like that, or is it fine to create a function and use the ECMA 5 version?

I'm doing something like this:

for(var i in data) {
   data[i].arr.forEach(function(...) {
      // do magic
   });
}
1
  • Can you please show the piece of code? Commented Mar 4, 2014 at 18:08

2 Answers 2

3

It is fine to use forEach, what it is suggesting here is that the function that you are passing to forEach should be created outside of the loop, something like the following:

var doMagic = function(...) {
    // do magic
};
for (var i in data) {
    data[i].arr.forEach(doMagic);
}

Creating functions within a loop is discouraged because it is inefficient, the JavaScript interpreter will create an instance of the function per loop iteration. Additional details are provided in JSLint Error Explanations: Don't make functions within a loop.

Sign up to request clarification or add additional context in comments.

5 Comments

Can you provide a benchmark for "inefficient"? While it must be a new function-object, I would be surprised if it was not well-optimized; the entire function body can be shared, for instance, and it won't create any more execution contexts.
Also jsperf.com/shared-vs-per-iteration, not sure what the difference is with your version.
It does more than my version. My version only creates the "new" functions in the same execution context, as this question shows.
I think these other versions of the test also have the same execution context, I think it might come down to how smart the browser is and possibly a difference between named vs unnamed functions.
They can't/don't have the same execution context. Because a new function with a new execution context creates the "new" functions. This will be slower (although perhaps not by much) because in this case new execution contexts must be created. (Although this argument is less strong vs the first link posted.)
1

Yes, it's fine to nest the constructs. It's also fine to create a "new" function each loop. And,

Performance differences when creating many "new" functions within the same execution context is an implementation detail; but it is not inherently slower. (See this jsperf test case1)

Even though a new function-object will be created in the "new" case each loop the same number of execution contexts are created - namely, the current execution context and when the function is called. Smarter JavaScript implementations can trivially take advantage of this; or they may not.

I prefer the inline-method in this particular case.


1 Test on the particular JavaScript implementation of course;

  • In IE 10, Chrome 33, and FF 23 show equivalent performance
  • FF 27 favors the "new" function case
  • Safari 5 buggers the numbers and runs slower in the "new" case

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.