首页 > 解决方案 > 使用函数声明与函数表达式在模块模式中切换变量

问题描述

我有一个模块模式,其中一个变量将 currentPlayer 设置为 1。我使用函数表达式来切换该变量

 const game = (() => {
    let currentPlayer = 1;

    const toggleCurrentPlayer = () => {
        if (currentPlayer == 1){
            currentPlayer = 2 ;
        }
        else {
            currentPlayer = 1;
        }
    };
    return {currentPlayer, toggleCurrentPlayer};
})();

如果我运行game.currentPlayer它会记录 1,然后我运行game.toggleCurrentPlayer(),并且它没有currentPlayer按预期更改,它仍然返回 1。

但是,toggleCurrentPlayer()使用 , 更改函数this似乎能够成功更改变量

function toggleCurrentPlayer(){
    if (this.currentPlayer == 1){      
        this.currentPlayer=2;
    }
    else if (this.currentPlayer == 2){
        this.currentPlayer=1;
    }
};

我知道函数声明和函数表达式对关键字有不同的含义this,但是为什么toggleCurrentPlayer()只有this关键字才能正常工作而不能自行设置变量呢?

标签: javascriptdesign-patternsfunction-declarationmodule-patternfunction-expression

解决方案


当函数执行

return {currentPlayer, toggeleCurrentPlayer};

它将变量的初始值复制currentPlayer到对象中。

返回的对象包含变量的值,而不是对变量本身的引用。重新分配变量对对象没有影响。

您可以做的是在函数内部创建一个对象,然后对其进行修改。

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);

另一种方法是使用获取变量的 getter 函数。

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());


推荐阅读