0

I have a piece of code that counts. The function showResultAndCount() shows counter and adds 1, the other function showResult() just shows counter.

I would like both functions to be able to work with the latest value of the variable counter. At the moment both functions seem to have their own version of the variable. How can I achieve this without using global variables?

This so elementary I assume it will be a duplicate, but I have no idea how this behaviour is called and therefore have no idea what I should be searching for on stack overflow or Google.

<script>
  function showResultAndCount(counter) {
    let someButton = document.getElementById('counter1');
    someButton.addEventListener('click', function() {
      counter++;
      alert(counter);
    });
    return counter;
  }

  function showResult(counter) {
    someButton = document.getElementById('counter2');
    someButton.addEventListener('click', function() {
      alert(counter);
    });
  }
</script>

<button id='counter1'>
  Show counter and count
</button>
<br /><hr />
<button id='counter2'>
  Show counter
</button>

<script>
  let counter = '0';
  counter = showResultAndCount(counter);
  showResult(counter);
</script>
Max
  • 386
  • 3
  • 16
  • 1
    what you are looking for is "global variable" . – Jonas Wilms Sep 14 '18 at 16:58
  • @JonasWilms is it possible to do this without global variables? The sample code is very simple, but I want this to happen in a bigger project where there would be quite a few of those variables and I read that it wasn't a good idea to use too many global variables. I'm sorry, I should have put that in there from the beginning. – Max Sep 14 '18 at 17:01
  • 2
    it only has to be global from the functions point of view, it doesnt have to be in the global scope (thats bad) – Jonas Wilms Sep 14 '18 at 17:02

2 Answers2

1

Try following - do not pass counter variable in the function by doing that you are creating separate copies of the variable.

<script>
  function showResultAndCount() {
    let someButton = document.getElementById('counter1');
    someButton.addEventListener('click', function() {
      counter++;
      alert(counter);
    });
  }

  function showResult() {
    someButton = document.getElementById('counter2');
    someButton.addEventListener('click', function() {
      alert(counter);
    });
  }
</script>

<button id='counter1'>
  click this text to show the counter and count
</button>
<br /><hr />
<button id='counter2'>
  click this text to show the counter
</button>

<script>
  let counter = 0;
  showResultAndCount();
  showResult();
</script>
Nikhil Aggarwal
  • 28,197
  • 4
  • 43
  • 59
1

This should do...

Note: It's a good practice to not pollute the global namespace hence the scoping.

(function(){
  let counter = 0;
  
  function showResultAndCount() {
   let someButton = document.getElementById('counter1');
   someButton.addEventListener('click', function() {
     counter++;
     alert(counter);
   });
  }

  function showResult() {
    someButton = document.getElementById('counter2');
    someButton.addEventListener('click', function() {
      alert(counter);
    });
  }
  
  showResultAndCount();
  showResult();
  
})();
<button id='counter1'>
  click this text to show the counter and count
</button>
<br /><hr />
<button id='counter2'>
  click this text to show the counter
</button>
Paul Okeke
  • 1,384
  • 1
  • 13
  • 19
  • 1
    Perfect! Since i posted this question, the duplicate mark pointed me towards scoping but while I understood what it was, I wasn’t sure how to achieve the desired behaviour in an elegant manner. Thanks for showing me! – Max Sep 14 '18 at 17:46
  • Just wondering, why is the last line of the JS code `})();` and not `}());`? – Max Sep 14 '18 at 20:22
  • 1
    Read on Immediately Invoked Function Expression(IIFE). In summary, it immediately calls the enclosing expression. Just like how you call a function, foo(); – Paul Okeke Sep 15 '18 at 06:34