1

I'm making a kind of HTML calculator to test something I have in mind. I've used a for loop to create the buttons of the keypad. The display is a text field. Then I used a for loop to add the functions in the buttons:

for (var i = 0; i < 10; i++)
{
    buttons[i].onclick = function()
    {
        display.value += i;
    };
}

What I was trying to do is to make, for example, buttons[0] add "0" to the value of the text field when clicked. Instead, clicking any button added "10" in the text field. Why? How can I make it right?

3
  • show us your full code Commented Aug 24, 2019 at 15:16
  • 1
    Possible duplicate of JavaScript closure inside loops – simple practical example Commented Aug 24, 2019 at 15:25
  • There really is no need to. This is the only snippet that needs to be changed and the rest of the code doesn't affect it. Buttons are of input type. Commented Aug 24, 2019 at 15:25

2 Answers 2

2

You almost got it right , you just need to change var to let in your loop declaration :

 for (let i = 0; i < 10; i++)
{
    buttons[i].onclick = function()
    {
        display.value += i;
    };
}

What's the difference between using "let" and "var"? Here you can get more info about your issue.

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

5 Comments

The solution actually worked by using Google Chrome instead of Edge, which I've resorted to using for several reasons. Which means that Edge doesn't support let?
Sure! But what if I want to use Edge? This solution doesn't work with Edge or IE.
@Bluberry17 it's hard to say why it didn't work in Edge, there can be a lot of reasons. I'm not sure if i can help you with that. Checking developer console for errors would be my best guess in this case.
Edge should have support for let / const variable declarations, see here: caniuse.com/#search=let so there might be something else going on.
it won't work in IE (seriously, who still uses that??), but this should definitely work in Edge
0

Your problem is that you are referencing i directly in your functions that you are binding to your Buttons. i will actually continue to exist even after you bound all your events, and its value will be the last value of the iteration 10. So whenever a click function runs, it looks up i and finds the last value you set (10) and takes that value. What you want to do is add a constant reference instead - so that you bind that value you have during the loop and keep that reference forever, no matter how i might change later.

for (var i = 0; i < 3; i++) {
    const localValue = i
    buttons[i].onclick = function()
    {
        counter += localValue;
        counterElement.innerHTML = counter
    };
}

I created a small example fiddle here: https://jsfiddle.net/4k8cds9n/ if you run this you should see the buttons in action. Some related reading for this topic would be around scopes in javascript, one good article: https://scotch.io/tutorials/understanding-scope-in-javascript

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.