Почему моя функция замыкания не хочет переназначать свою переменную родительской функции, если она находится внутри оператора if? - PullRequest
0 голосов
/ 28 января 2020

Я создал эту фабричную функцию, которую использую для описания логики игры c. Я использую внутреннюю функцию для переключения игроков в игре. Проблема в том, что когда я пытаюсь переназначить текущий плеер изнутри внутренней функции, он не работает. Текущий игрок никогда не меняется. Я думаю, что это что-то о закрытии, что я на самом деле не gr asp. Не могли бы вы объяснить мне, что мне не хватает. Вот фрагмент кода, над которым я работаю:

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;

Ответы [ 3 ]

1 голос
/ 28 января 2020

Это делает переназначение переменной.

Проблема в том, что возвращаемый объект имеет свойства с копиями значений этих переменных, а не ссылками на переменные.

Таким образом, 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 голосов
/ 28 января 2020

Ваш код возвращает значение из 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);
0 голосов
/ 28 января 2020

Вы должны взять ссылку на объект и хранить игроков внутри, а не снаружи, потому что объект не меняет состояние.

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