1

I am familiar with JavaScript closures. I discovered closure issues while working on my own projects, years ago. I have also included the famous for-loop-button question while interviewing candidates.

Now, I got asked this question with jQuery. And I cannot, for the life of me, solve the problem.

$(document).ready( function() {
  var buttons = $('button');

  for( var i = 0; i < buttons.length; ++i ) {
    buttons.eq(i).click(
        // ONLY EDIT THE CODE BELOW THIS LINE
        function() {
            $('ul').append('<li>' + i + '</li>')
        }
        // ONLY EDIT THE CODE ABOVE THIS LINE
    );
  }
});

Does anyone know how to create the necessary closure here, within the constraints?

I tried wrapping the anonymous function in parenthesis, returning an inner function, etc. Nothing worked.

https://jsfiddle.net/hmw0gk4c/791/

Thanks.

Dev
  • 13
  • 4
  • Unfortunately the question closed so I can't post an answer. The issue is that you need to pass the index `i` as a parameter through the scope of the parent function; the child function can be anonymous. Here's a fiddle that works: https://jsfiddle.net/hmw0gk4c/867/ – Greenstick Jul 18 '18 at 23:46
  • 1
    My 'i' was in the wrong function. – Dev Jul 19 '18 at 02:44
  • I disagree that this question had already been answered elsewhere. If I could have found the answer, I wouldn't have asked. This particular problem requires the solution to be coded within the for-loop. Similar questions provide a solution that calls on a function outside of the for-loop. – Dev Jul 19 '18 at 02:47
  • Thanks everyone! – Dev Jul 19 '18 at 02:53
  • 1
    Also, regarding 'Already Answered', the question linked at the top is for vanilla JS. This question concerned jQuery which requires a slightly different syntax. – Dev Jul 19 '18 at 03:05

3 Answers3

0

Will this be what you're after?

$(document).ready( function() {
 var buttons = $('button');

 for( var i = 0; i < buttons.length; ++i ) {
  buttons.eq(i).click(
   // ONLY EDIT THE CODE BELOW THIS LINE
   return (function() {
    $('ul').append('<li>' + i + '</li>')
   })();
   // ONLY EDIT THE CODE ABOVE THIS LINE
  );
 }
});
andriusain
  • 1,211
  • 10
  • 18
  • 1
    This answer will work for vanilla JS. But the code you wrote is inside of the 'click' function. So the answer needs to be an object/function, rather than a statement. – Dev Jul 19 '18 at 02:51
0

This does the trick:

$(document).ready( function() {
  var buttons = $('button');

  for( var i = 0; i < buttons.length; ++i ) {
    buttons.eq(i).click(
        // ONLY EDIT THE CODE BELOW THIS LINE
        function() { 
                var i2 = i + 1; 
                return function() {
                    $('ul').append('<li>' + i2 + '</li>');
                }
            }()
        // ONLY EDIT THE CODE ABOVE THIS LINE
    );
  }
});
AaronHolland
  • 1,595
  • 1
  • 16
  • 32
0

This worked for me:

$(document).ready( function() {
  var buttons = $('button');
  for( var i = 0; i < buttons.length; ++i ) {
    buttons.eq(i).click(
      // ONLY EDIT THE CODE BELOW THIS LINE
      (function(y) {
        return (function() {
          $('ul').append('<li>' + y + '</li>')
        });
      })(i)
      // ONLY EDIT THE CODE ABOVE THIS LINE
    );
  }
});
jkchu
  • 98
  • 10
  • Double parenthesis. Didn't try that. It works. Thanks. I'm giving you the check (if I can) for not creating a new var. – Dev Jul 19 '18 at 02:44
  • The parentheses are not what make this answer a solution; rather, it is the passing of the index `i` (as the `y` parameter) through the scope of the parent function, making it available to the child function's scope. – Greenstick Aug 10 '18 at 16:57