76

What would be the correct way to solve the jslint error in this case? I'm adding a getter function to an object which uses this. I don't know how to do this without creating the function inside the loop.

for (var i = 0; i<processorList.length; ++i) {
   result[i] = {
       processor_: timestampsToDateTime(processorList[i]),
       name_: processorList[i].processorName,
       getLabel: function() { // TODO solve function in loop.
            return this.name_;
       }
   };
}
Thijs Koerselman
  • 21,680
  • 22
  • 74
  • 108
  • Why not silence the jslint error altogether? [Here's](http://stackoverflow.com/a/40060701/307454) how. – lifebalance Oct 22 '16 at 12:39
  • 5
    Because the error is there for a reason. I don't think its very nice to write code like this where numerous of the exact same functions get created for no real reason. – Thijs Koerselman Oct 26 '16 at 08:02
  • 1
    _Sometimes_ jslint is not necessarily the ultimate guide to proper coding style... – lifebalance Oct 26 '16 at 18:31
  • 1
    True (I think, I haven't used jslint for years), but any code that creates a lot of the same resources with no real reason is bad code in my book. The only situation in which that would be ok is if it results in performance gains. In this case you could argue that it makes the code a little more readable, but I believe that's very marginal. As a javascript developer you need to understand how `this` works. – Thijs Koerselman Oct 27 '16 at 20:29

1 Answers1

113

Move the function outside the loop:

function dummy() {
    return this.name_;
}
// Or: var dummy = function() {return this.name;};
for (var i = 0; i<processorList.length; ++i) {
   result[i] = {
       processor_: timestampsToDateTime(processorList[i]),
       name_: processorList[i].processorName,
       getLabel: dummy
   };
}

... Or just ignore the message by using the loopfunc option at the top of the file:

/*jshint loopfunc:true */
tom
  • 2,189
  • 2
  • 15
  • 27
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • 1
    Ah I didn't think the "this" pointer would still work in that way. Isn't it pointing to the dummy function instead of the object at result[i]? In other words is name_ still correctly found? – Thijs Koerselman Apr 25 '12 at 17:17
  • 3
    @0x80 `this` points to the function's context, which is `results[i]` in this case. http://jsfiddle.net/W5vfw/ – Rob W Apr 25 '12 at 17:22
  • 2
    Wonderful! Thanks for explaining this clearly. This was one of those things I never felt confident about in Javascript. – Thijs Koerselman Apr 25 '12 at 17:36
  • @RobW: May I know, what makes the difference by just calling a named function in the loop? – Amol M Kulkarni Jan 30 '13 at 09:31
  • 14
    @AmolMKulkarni When the function expression is put inside the loop, it is constructed on each iteration. Moving the function expression/declaration outside the loop has some performance benefits: http://jsperf.com/closure-vs-name-function-in-a-loop/2 – Rob W Jan 30 '13 at 09:49
  • 2
    What happens when you want to pass some parameters to the function? – King Julien Aug 02 '13 at 20:37
  • @Levani Then you usually need a [closure](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example). – Rob W Aug 02 '13 at 20:39
  • What if, in this example, the dummy function itself was creating a function? Should that function be declared outside the dummy function? @RobW – ErikAGriffin Jul 08 '15 at 19:17
  • @ErikAGriffin It depends. It is a trade-off between performance and readability (and you should usually favor readability). See e.g. http://stackoverflow.com/questions/19779752/javascript-nested-function-performance for some arguments for and against nesting functions. – Rob W Jul 08 '15 at 19:39
  • @RobW The code for the jshint option contains an erroneous space (at least in the version that I'm using). It should be `/*jshint loopfunc:true */` (no space before the j), and it should be at the top of the file – tom Apr 28 '17 at 23:50
  • Amazing! Thanks brother :) – Majedur Jul 27 '23 at 12:10