Ser Ber
Ser Ber

Reputation: 15

How to change two different global variables from inside a Function in JavaScript

this is my first question here in StackOverflow..

I'm studying JavaScript right now and I'm trying to refactor some code to make it easier to read and shorter.

I need to add a point to a player score in a display when a button is clicked, so I created a function "addPoint" that takes 2 paramenters, one is the player score, and the other is the player display where I display the points...

This is what I have...

var p1 = document.querySelector("#p1");
var p2 = document.getElementById("p2");
var dis1 = document.querySelector("#dis1");
var dis2 = document.getElementById("dis2");
var btnReset = document.querySelector("#reset");
var input = document.getElementsByTagName("input");
var winDis = document.querySelector("#num");
var p1Score = 0;
var p2Score = 0;
var gameOver = false;
var winScore = 5;

p1.addEventListener("click", function() {
  addPoint(p1Score, dis1);
});

p2.addEventListener("click", function() {
  addPoint(p2Score, dis2);
});

btnReset.addEventListener("click", function() {
  reset();
});

input.addEventListener("change", function() {
  winDis.textContent = this.value;
  winScore = Number(this.value);
  reset();
});

function addPoint(pScore, display) {
  if (!gameOver) {
    pScore++;    
    if (pScore === winScore) {
      display.classList.add("winner");
      gameOver = true;
    }
    display.textContent = pScore;    
  }
}

function reset() {
  p1Score = 0;
  p2Score = 0;
  dis1.textContent = p1Score;
  dis2.textContent = p2Score;
  dis1.classList.remove("winner");
  dis2.classList.remove("winner");
  gameOver = false;
}

The thing is that when I click on any of the buttons, the function adds 1 to the score, but it never changes the global variables p1Score or p2Score, so whenever I click a player button again, it shows 1 all the time because it takes the initial value of those variables, so my function it's not returning the new value to those variables, my question is what am I missing here? I can't find an answer here to my particular problem.

Thanks in advance

Upvotes: 1

Views: 55

Answers (2)

Rounin
Rounin

Reputation: 29453

If you wish to access global variables from inside a function, you do not need to pass the values of those global variables as function parameters.

Instead, you can refer to the global variables directly from inside the function.

Why does this work? How can a reference to a variable inside a function mean anything when that variable is absent from the function scope?

It's because any references to variables absent from any present scope will lead the javascript engine to search the scope above (and if the variables are absent there too, it will search the next scope above etc. all the way up to the global scope).

So, if you have these global variables:

const dis1 = document.querySelector("#dis1");
let p1Score = 0;

then, instead of:

p1.addEventListener("click", function() {
  addPoint(p1Score, dis1);
});

and

function addPoint(pScore, display) {
  if (!gameOver) {
    pScore++;    
    if (pScore === winScore) {
      display.classList.add("winner");
      gameOver = true;
    }
    display.textContent = pScore;    
  }
}

you can write:

p1.addEventListener("click", function() {
  addPoint();
});

and

const addPoint = () => {
  if (!gameOver) {
    p1Score++;    
    if (p1Score === winScore) {
      dis1.classList.add("winner");
      gameOver = true;
    }
    dis1.textContent = p1Score;    
  }
}

Upvotes: 0

giuseppedeponte
giuseppedeponte

Reputation: 2391

I think your problem is this: When you do this addPoint(p1Score, dis1); you are not passing the variable p1Score to your function, but only its current value.
Inside the addPoint function this value, that is just a number, is assigned to a new variable, the argument pScore.
So, when you do pScore++ you are adding 1 to the new variable but not to the original p1Score. You can modify this variable only by explicitly doing p1Score = // something. One solution is to move the adding inside the event handler:

p1.addEventListener("click", function() {
  p1Score++
  addPoint(p1Score, dis1);
});
function addPoint(pScore, display) {
  if (!gameOver) {   
    if (pScore === winScore) {
      display.classList.add("winner");
      gameOver = true;
    }
    display.textContent = pScore;    
  }
}

or use an object (whose properties are accessible as strings) to store your scores:

var p1 = document.querySelector("#p1");
var p2 = document.getElementById("p2");
var dis1 = document.querySelector("#dis1");
var dis2 = document.getElementById("dis2");
var btnReset = document.querySelector("#reset");
var input = document.getElementsByTagName("input");
var winDis = document.querySelector("#num");

var scores = {
    "p1": 0,
    "p2": 0
}
var gameOver = false;
var winScore = 5;

p1.addEventListener("click", function() {
  addPoint('p1', dis1);
});

p2.addEventListener("click", function() {
  addPoint('p2', dis2);
});

btnReset.addEventListener("click", function() {
  reset();
});

input.addEventListener("change", function() {
  winDis.textContent = this.value;
  winScore = Number(this.value);
  reset();
});

function addPoint(player, display) {
  if (!gameOver) {
    scores[player] += 1;
    if (scores[player] === winScore) {
      display.classList.add("winner");
      gameOver = true;
    }
    display.textContent = scores[player];    
  }
}

function reset() {
  scores.p1 = 0;
  scores.p2 = 0;
  dis1.textContent = 0;
  dis2.textContent = 0;
  dis1.classList.remove("winner");
  dis2.classList.remove("winner");
  gameOver = false;
}

Upvotes: 1

Related Questions