4

Using this code:

addDefaultComments() {
    $('.image').each((index, image) => {
      Comment.defaults.forEach((comment) => {
        debugger;
        $('#images').find(`ul[data-id=${imageId}] ul#comments-${imageId}`).append(`<li>${comment.commentContent}</li>\n`);
      })
    })
  }

At this debugger statement, shouldn't I have access to image and index? When I call them, it says they aren't defined. Isn't that weird?

Proof that something odd is going on:

enter image description here

enter image description here

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Jwan622
  • 11,015
  • 21
  • 88
  • 181
  • (Side note on terminology: You don't "call" variables, you "use" them.) – T.J. Crowder Nov 01 '17 at 17:59
  • Can you try using a regular function rather than a fat arrow function for your .each function. Not sure how jQuery implements .each, but I'm pretty sure they use an `arguments` object. – darthaditya Nov 01 '17 at 18:01
  • attached screenshots – Jwan622 Nov 01 '17 at 18:01
  • 1
    wow changing it to a regular function worked @darthaditya. Wtf happened? – Jwan622 Nov 01 '17 at 18:03
  • 2
    That shouldn't happen. The only scope difference in fat arrow functions should be for `this`. – Barmar Nov 01 '17 at 18:04
  • Okay that's great. It's probably because jQuery uses an `arguments` object to iterate over the child nodes. Fat arrow functions don't play nice with the `arguments` object. – darthaditya Nov 01 '17 at 18:05
  • 3
    I suspect this is a debugger artifact due to the fact that the nested function doesn't use those variables, so they're not included in the closure. – Barmar Nov 01 '17 at 18:05
  • Does this problem happen if you put `console.log(index)` in the nested function? – Barmar Nov 01 '17 at 18:06
  • @darthaditya: No. It's true that arrow functions don't have their own `arguments` binding, but that has nothing to do with jQuery's use of `arguments` in *its* functions. – T.J. Crowder Nov 01 '17 at 18:08
  • See [this MDN link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_binding_of_arguments) for more information. – darthaditya Nov 01 '17 at 18:09
  • @T.J.Crowder, Maybe you're right, we are missing something here. – darthaditya Nov 01 '17 at 18:10
  • did I not put in enough code? – Jwan622 Nov 01 '17 at 18:10
  • @Barmar same deal, just tried it. – Jwan622 Nov 01 '17 at 18:10
  • @darthaditya If it's using `arguments`, that's used outside the callback function, how can it cause a problem inside the callback? The only issue I can think of with `.each()` and arrow functions is https://stackoverflow.com/questions/36548683/elems-each-with-fat-arrow with trying to use `this` in the callback. – Barmar Nov 01 '17 at 18:14

1 Answers1

3

At this debugger statement, shouldn't I have access to image and index?

Yes, you should; and you do — unless they get optimized away because you're not using them. That's what's happening here. Chrome is aggressively optimizing the function because you don't actually use index or image anywhere. If you use them, they're there:

Proof that it works fine with arrow functions in an up-to-date version of Chrome

(Here's that fiddle if you want to play with it: http://jsfiddle.net/Lbe2pue0/)

They're only not there if you don't use them:

Proof they aren't there if you don't use them

(And here's that fiddle: http://jsfiddle.net/Lbe2pue0/1/)

(I think it's very interesting that Chrome does this optimization in an arrow function but not in a function function...)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Okay, but then why does it work when using a regular function? – darthaditya Nov 01 '17 at 18:23
  • `(I think it's very interesting that Chrome does this optimization in an arrow function but not in a function function...)` ...Ah maybe a quirk in Chrome then. You learn something new everyday. – darthaditya Nov 01 '17 at 18:25
  • @darthaditya: Different optimization. Really, with the `debugger;` statement there, you could argue that it should optimize the arrow function like that (for this very reason). But it does (for now, anyway). But this is just debugger stuff; those parameters *are* in scope and if you use them in actual code, they'll be there (won't get optimized away). – T.J. Crowder Nov 01 '17 at 18:25
  • yo this be cray cray – Jwan622 Nov 01 '17 at 18:33