I have a module pattern with a variable setting the currentPlayer to 1. I use a function expression to toggle that variable
const game = (() => {
let currentPlayer = 1;
const toggleCurrentPlayer = () => {
if (currentPlayer == 1){
currentPlayer = 2 ;
}
else {
currentPlayer = 1;
}
};
return {currentPlayer, toggleCurrentPlayer};
})();
If I run game.currentPlayer it logs 1, I then run game.toggleCurrentPlayer(), and it doesn't change currentPlayer as intended, it still returns 1.
However, changing the toggleCurrentPlayer() function using this, seems to be able to change the variable successfully
function toggleCurrentPlayer(){
if (this.currentPlayer == 1){
this.currentPlayer=2;
}
else if (this.currentPlayer == 2){
this.currentPlayer=1;
}
};
I know function declarations and function expressions have different meanings for the keyword this, but why would the toggleCurrentPlayer() only work properly with the this keyword and not be able to set the variable on its own?
1 Answer 1
When the function does
return {currentPlayer, toggeleCurrentPlayer};
It copies the initial value of the currentPlayer variable into the object.
The returned object contains the value of the variable, not a reference to the variable itself. Reassigning the variable has no effect on the object.
What you can do instead is create an object inside the function, and modify that.
const game = (() => {
let obj = {
currentPlayer: 1,
toggleCurrentPlayer: () => {
if (obj.currentPlayer == 1) {
obj.currentPlayer = 2;
} else {
obj.currentPlayer = 1;
}
}
};
return obj;
})();
console.log(game.currentPlayer);
game.toggleCurrentPlayer();
console.log(game.currentPlayer);
Another way to do it is with a getter function that retrieves the variable.
const game = (() => {
let currentPlayer = 1;
const toggleCurrentPlayer = () => {
if (currentPlayer == 1){
currentPlayer = 2 ;
}
else {
currentPlayer = 1;
}
};
const getCurrentPlayer = () => currentPlayer
return {getCurrentPlayer, toggleCurrentPlayer};
})();
console.log(game.getCurrentPlayer());
game.toggleCurrentPlayer();
console.log(game.getCurrentPlayer());
8 Comments
obj? I could change it to use game.currentPlayer in the toggle function.this in a method but an arrow function closing over obj. But yeah, given that game is const anyway, using that seems fine as well.Explore related questions
See similar questions with these tags.
toggleCurrentPlayeris declared. It's about modifying a local variable vs. modifying an object property.game.currentPlayerproperty is not a live view on the variable, it just keeps the value that you created initially.game.currentPlayer = 3;, but only the code inside the module scope can access and assign the local variablelet currentPlayer)