从其他模块中的工厂函数调用函数不起作用

Calling a function from factory function in other module doesn't work

我有两个模块:boardObject 和 displayController...还有一个工厂函数:playerFactory...我想用 playerFactory 中的函数更新数组,但我得到的错误不是函数。

const playerFactory = () => {
    const playTurn = (event) => {
        const id = boardObject.cells.indexOf(event.target);
        boardObject.boardArray[id] = currentPlayer;
        boardObject.render();
        return id;
    };

    return { playTurn   };
};
const displayController = (() => {
    const playerOne = 'X';
    const playerTwo = 'O'
    const gameBoard = document.querySelector(".game_board");
    let currentPlayer = playerOne;
    
    const switchPlayer = () => {
        currentPlayer = currentPlayer === playerOne ? playerTwo : playerOne;
    }
    
    gameBoard.addEventListener("click", (event) => {
      if (event.target.classList.contains("cell")) {
        if (event.target.textContent === "") {
          event.target.textContent = currentPlayer;
          switchPlayer();
          //   const id = boardObject.cells.indexOf(event.target);
          //   boardObject.boardArray[id] = currentPlayer;
          //   boardObject.render();
          currentPlayer.playTurn(event.target);
        }
      }
    });
})();

可能是什么问题? 如果有人想查看所有代码,这也可能有所帮助:

// player factory...
const playerFactory = () => {
  const playTurn = (event) => {
    const id = boardObject.cells.indexOf(event.target);
    boardObject.boardArray[id] = currentPlayer;
    boardObject.render();
  };

  return {
    playTurn
  };
};

// Gameboard object...
const boardObject = (() => {
  let boardArray = ['', '', '', '', '', '', '', '', ''];

  const cells = Array.from(document.querySelectorAll(".cell"));
  // displays the content of the boardArray...
  const render = () => {
    boardArray.forEach((mark, idx) => {
      cells[idx].textContent = boardArray[idx];
    });
  };

  return {
    boardArray,
    render,
    cells
  };
})();

// Display controller ...
const displayController = (() => {
  const playerOne = 'X';
  const playerTwo = 'O'
  const gameBoard = document.querySelector(".game_board");
  let currentPlayer = playerOne;

  const switchPlayer = () => {
    currentPlayer = currentPlayer === playerOne ? playerTwo : playerOne;
  }

  gameBoard.addEventListener("click", (event) => {
    if (event.target.classList.contains("cell")) {
      if (event.target.textContent === "") {
        event.target.textContent = currentPlayer;
        switchPlayer();
        //   const id = boardObject.cells.indexOf(event.target);
        //   boardObject.boardArray[id] = currentPlayer;
        //   boardObject.render();

        ////////
        currentPlayer.playTurn(event); // this is the problem, dunno why?!?!?!?
      }
    }
  });
})();
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Roboto', sans-serif;
  background: #BEE9E8;
}

header {
  background: #1B4965;
  text-align: center;
  color: #62B6CB;
  padding-top: 20px;
  padding-bottom: 10px;
}

.game_board {
  display: grid;
  width: 500px;
  height: 500px;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: repeat(3, 1fr);
  margin: 0 auto;
  margin-top: 40px;
  border: 5px solid #1B4965;
  border-radius: 10px;
}

.cell {
  border: 5px solid #1B4965;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #62b6cb;
  color: #1b4965;
  font-size: 4em;
  font-weight: bold;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Tic Tac Toe</title>
  <link rel="stylesheet" href="./style.css">
  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap" rel="stylesheet">
</head>

<body>
  <header>
    <h1>Tic - Tac - Toe<br>The Odin Project</h1>
  </header>


  <div class="game_board">
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
  </div>




  <script src="./index.js" defer></script>
</body>

</html>

currentPlayer 只是一个字符串 XO,它没有 playTurn() 方法。

您需要调用playerFactory()来获取对象。在我下面的代码中,我使用

const player = playerFactory();

我不太确定你一开始为什么需要这个对象;它不保持任何状态。但也许这是您打算稍后添加的内容。

此外,playTurn() 需要传递 currentPlayer 字符串,以便它可以将其分配给网格元素。它是 gameController 中的局部变量,因此无法直接访问它。

// player factory...
const playerFactory = () => {
  const playTurn = (event, currentPlayer) => {
    const id = boardObject.cells.indexOf(event.target);
    boardObject.boardArray[id] = currentPlayer;
    boardObject.render();
  };

  return {
    playTurn
  };
};

// Gameboard object...
const boardObject = (() => {
  let boardArray = ['', '', '', '', '', '', '', '', ''];

  const cells = Array.from(document.querySelectorAll(".cell"));
  // displays the content of the boardArray...
  const render = () => {
    boardArray.forEach((mark, idx) => {
      cells[idx].textContent = boardArray[idx];
    });
  };

  return {
    boardArray,
    render,
    cells
  };
})();

// Display controller ...
const displayController = (() => {
  const player = playerFactory();
  const playerOne = 'X';
  const playerTwo = 'O'
  const gameBoard = document.querySelector(".game_board");
  let currentPlayer = playerOne;

  const switchPlayer = () => {
    currentPlayer = currentPlayer === playerOne ? playerTwo : playerOne;
  }

  gameBoard.addEventListener("click", (event) => {
    if (event.target.classList.contains("cell")) {
      if (event.target.textContent === "") {
        event.target.textContent = currentPlayer;
        switchPlayer();
        //   const id = boardObject.cells.indexOf(event.target);
        //   boardObject.boardArray[id] = currentPlayer;
        //   boardObject.render();

        ////////
        player.playTurn(event, currentPlayer);
      }
    }
  });
})();
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Roboto', sans-serif;
  background: #BEE9E8;
}

header {
  background: #1B4965;
  text-align: center;
  color: #62B6CB;
  padding-top: 20px;
  padding-bottom: 10px;
}

.game_board {
  display: grid;
  width: 500px;
  height: 500px;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: repeat(3, 1fr);
  margin: 0 auto;
  margin-top: 40px;
  border: 5px solid #1B4965;
  border-radius: 10px;
}

.cell {
  border: 5px solid #1B4965;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #62b6cb;
  color: #1b4965;
  font-size: 4em;
  font-weight: bold;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Tic Tac Toe</title>
  <link rel="stylesheet" href="./style.css">
  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap" rel="stylesheet">
</head>

<body>
  <header>
    <h1>Tic - Tac - Toe<br>The Odin Project</h1>
  </header>


  <div class="game_board">
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
    <div class="cell"></div>
  </div>




  <script src="./index.js" defer></script>
</body>

</html>