4

I know that the below is perfectly viable:

var numberArray = [];

function addNumber(number) {
  numberArray.push(number);
}

and then:

<input type="button" value="Save" onclick="addNum(10);">
<input type="button" value="Save" onclick="addNum(990);">
...

But is it possible, for a better code, to have both my array and my action on the same function, and then trigger it on a click event, thus populating my array? Asking because, doing this:

function addNumber(number) {
  var numberArray = [];
  numberArray.push(number);
}

Does not increase the array values.

I know that inline click events is considerate a bad practice nowadays, but it's for learning purposes. All other answers here reference the array as a global scope, which is what I'm trying to avoid.

Edit: Ok if the above is not possible, any answer avoiding the global scope usage is valid.

8
  • 4
    Wrap all the code in an IIFE, or create an object, which has addNumber as a method, and numberArray as a property. To utilize one of these, you need to use addEventListener to attach events. Commented Sep 15, 2016 at 15:14
  • 2
    @Teemu: And then add the click handler in JavaScript since addNumber will no longer be global. Commented Sep 15, 2016 at 15:15
  • window.addNumber = function... inside the IIFE Commented Sep 15, 2016 at 15:16
  • 3
    @taguenizy Instead of this, using the standard addEventListener is a much better alternative. Commented Sep 15, 2016 at 15:16
  • 1
    Because for some reason addNumber being global too, doesn't seem to bother you, one more alternative comes into mind. Functions are also objects, you could add numberArray as a property to addNumber. Then refer it in addNumber (or anywhere) like so: addNumber.numberArray.push(...). This way you can even keep the inline listeners. Commented Sep 15, 2016 at 15:55

3 Answers 3

4

You can use a Self-Invoking Function, for creating a local scope, then you can add eventListeners instead using onclick directive.

(function () {
   var numberArray = [];

   function addNumber() {
       var child = this;
       var number = parseInt(child.getAttribute('data-number'), 10);

       numberArray.push(number);
       console.log(numberArray);
   }

   var _elms = document.getElementsByClassName('add-number-input');

   for (var i = 0; i < _elms.length; i++)
       _elms[i].addEventListener('click', addNumber);
})();

Add to a class .add-number-input to your inputs:

<input class="add-number-input" data-number="10" ...>
<input class="add-number-input" data-number="990" ...>

Now both your array and your function isn't on global scope.

http://codepen.io/rdsedmundo/pen/EgKGXK

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

1 Comment

You should add the "radix" to parseInt: parseInt('', 10);
1

It can be achieved using self-invoking function. By this the numberArray will be in that function's scope and the method addNumber will be exposed as global.

(function(){
    var numberArray = [];
    window.addNumber = function(number) {
        numberArray.push(number);
    }
})();

Comments

0

I'm afraid there isn't- at least not one that doesn't defeat your aim of writing better code. Declaring numberArray in addNum() means it is created, initialized and destroyed each time the function is called. I advise that you use the global scope option. However, if you MUST use the options afforded by the other answers because of some program requirements, please do so.

1 Comment

The other answers are aiming towards better practices, especially Edmundo's.

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.