在if语句中,为什么我的闭包函数不希望重新分配其父函数变量?

问题描述 投票:-1回答:4

我已经创建了此工厂函数,用于描述游戏逻辑。我使用内部功能来切换游戏中的玩家。问题是,当我尝试从内部功能中重新分配当前播放器时,它不起作用。当前玩家永远不会改变。我猜这是关于关闭的事情,我不太了解。您能给我解释一下我所缺少的吗?这是我正在处理的代码:

const game = (() => {
    let player1 = "Jim";
    let player2 = "Mary";
    let currentPlayer = player1;

    const switchPlayers = () => { //This closure function is supposed to reassign the value of currentPlayer above. But it does not do it.
        if (currentPlayer === player1) {
            currentPlayer = player2;
        } else {
            currentPlayer = player1;
        }
        return currentPlayer;
    };

    return {currentPlayer, switchPlayers};

})();

game.switchPlayers // works as needed and switches the players every time it is invoked but does not reassign the variable within its parent function;
game.currentPlayer // does not get reassigned, when switchPlayers function is invoked, and returns player1 as was assigned at the start;
javascript closures factory
4个回答
0
投票

您的代码返回currentPlayer,当原始对象的属性更新时,该值未更新。因此,闭包运行良好,但事实是您的返回值未指向更新的对象,它只是一个新值,在return语句时将保持不变。

您需要使用以下函数返回值。

let game = (() => {
  let player1 = "Jim";
  let player2 = "Mary";
  let currentPlayer = player1;

  const switchPlayers = () => { //This closure function is supposed to reassign the value of currentPlayer above. But it does not do it.
    if (currentPlayer === player1) {
      currentPlayer = player2;
    } else {
      currentPlayer = player1;
    }
    return currentPlayer;
  };
  
  const getCurrentPlayer = () => currentPlayer;

  return {
    currentPlayer,
    switchPlayers,
    getCurrentPlayer
  };

})();

game.switchPlayers();
console.log(game.currentPlayer);
console.log(game.getCurrentPlayer());

或只需在函数的currentPlayer指针上定义属性this,然后将其用作类型(使用new关键字),如下所示。

function GameType() {
   let player1 = "Jim";
   let player2 = "Mary";
   this.currentPlayer = player1;

   this.switchPlayers = () => { //This closure function is supposed to reassign the value of currentPlayer above. But it does not do it.
     if (this.currentPlayer === player1) {
       this.currentPlayer = player2;
     } else {
       this.currentPlayer = player1;
     }
     return this.currentPlayer;
   };
 }

let game = new GameType();

console.log(game.currentPlayer);

game.switchPlayers();
console.log(game.currentPlayer);

1
投票

确实重新分配了变量。

问题是您返回的对象具有这些变量的值的副本的属性,而不是对变量的引用。

因此let currentPlayer被更改,但game.currentPlayer仍包含原始值的副本。

摆脱变量,而只是修改对象属性。

const game = (function() {
  const player1 = "Jim";
  const player2 = "Mary";
  let o = {
    currentPlayer: player1
  };

  const switchPlayers = () => {
    if (o.currentPlayer === player1) {
      o.currentPlayer = player2;
    } else {
      o.currentPlayer = player1;
    }
    return o.currentPlayer;
  };

  o.switchPlayers = switchPlayers;
  return o;
})();

console.log(game.currentPlayer);
console.log(game.currentPlayer);
console.log(game.switchPlayers());
console.log(game.currentPlayer);
console.log(game.currentPlayer);

0
投票

您需要获取对象引用并将玩家存储在内部而不是外部,因为对象不会更改状态。

const game = function() {
    let player1 = "Jim";
    let player2 = "Mary";
    let currentPlayer = player1;

    const
        switchPlayers = () => {
            object.currentPlayer = object.currentPlayer === player1 
                ? player2
                : player1;
            return object.currentPlayer;
        },
        object = { currentPlayer, switchPlayers };
    
    return object;
}();

console.log(game.switchPlayers());
console.log(game.currentPlayer);
console.log(game.switchPlayers());
console.log(game.currentPlayer);

-1
投票

也许这对你有用

let player1 = "Jim";
    let player2 = "Mary";
    let currentPlayer = player1;
    
    const getCurrent = function () {
      return currentPlayer;
    }

    const switchPlayers = () => { //This closure function is supposed to reassign the value of currentPlayer above. But it does not do it.
        if (currentPlayer === player1) {
            currentPlayer = player2;
        } else {
            currentPlayer = player1;
        }
        return currentPlayer;
    };

    return {currentPlayer: getCurrent(), switchPlayers};

})();
© www.soinside.com 2019 - 2024. All rights reserved.