"this" 值,在 Javascript 中使用工厂函数、模块、事件监听器和 IIFE 创建 Tic Tac Toe 游戏时

"this" value, when creating a Tic Tac Toe game using Factory Functions, Modules, Event Listeners, and IIFE's in Javascript

我正在开发一款 Tic Tac Toe 游戏,玩家轮流在棋盘上做标记。

在这个阶段,我试图让棋盘在每次单击方块时在玩家之间交替。因此,当玩家 1 单击棋盘时,玩家 1 的符号显示在单击的方格上,然后轮到玩家 2 select 一个方格。

这是我第一次使用立即调用的函数表达式 (IIFE) 和工厂函数,我很难让这些模块很好地协同工作。

过程和问题是这样的:

我不明白为什么这不能正常工作,我很难理解如何在模块之间使用对象。

我查看了模块、IIFE 和 eventListeners,但似乎找不到一个很好的例子来结合所有这些并帮助我理解问题的根源。

//Gameboard array
var boardModule = (() => {

  //Select div for board
  let boardContainer = document.querySelector("#boardContainer")
  let boardArray = ["x", "o", "x", "o", "x", "o", "x", "o", "x"];

  //Module Player Selection

  const gameFunctions = (() => {

    // Onclick function for board

    let currentPlayer;

    // Selection module
    const getPlayer = () => {

      switch (currentPlayer) {
        case undefined:
          currentPlayer = 1;
        case 1:
          console.log(this);
          this.innerHTML = "PLAYER 1 SELECTION";
          return currentPlayer = 2;
        case 2:
          this.innerHTML = "PLAYER 2 SELECTION"
          return currentPlayer = 1;
      }


    };


    return {
      getPlayer
    };

  })();



  //Module: Built board with for each

  const boardGenerator = () => {

    boardArray.forEach(element => {
      let square = document.createElement("div")
      square.classList.add("squareStyle")
      square.innerHTML = element
      square.addEventListener("click", gameFunctions.getPlayer);

      //Append to board
      boardContainer.appendChild(square);

    });
  }

  //Module: Build players

  const Player = (name, mark) => {
    getname = () => name;
    getmark = () => mark;

    const welcome = person => {
      console.log(`Welcome to ${person.getname()}`)
    }

    return {
      getname,
      getmark,
      welcome
    }
  }

  player1 = Player("player1", "X");
  player2 = Player("player2", "0");

  //Module: Square Selector
  return {
    boardGenerator,
    gameFunctions
  };

})();


boardModule.boardGenerator();
html,
body {
  height: 100%;
}

* {
  font-family: Graphik Regular;
}

.container {
  height: 100%;
  padding: 0;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

#boardContainer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  position: absolute;
  margin: 0 auto;
  width: 300px;
  height: auto;
}

.squareStyle {
  display: flex;
  height: 100px;
  width: 100px;
  background-color: red;
  position: relative;
  align-items: center;
  justify-content: center;
}
<!DOCTYPE html>
<meta charset="UTF-8">
<html lang="en">
<head>
  <link rel="stylesheet" type="text/css" href="style.css">
  </stylesheet>
  <script type="text/javascript" src="http://livejs.com/live.js"></script>
</head>
<body>
  <div class="container">
    <div id="boardContainer">
    </div>
  </div>
  <script src="script.js"></script>
</body>
</html>

发生这种情况是因为您正在使用箭头函数。箭头函数总是绑定到父作用域,在你的例子中是 window 对象。

看看这个来自 MDN Arrow Function Docs 的例子:

'use strict';

var obj = { // does not create a new scope
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log(this.i, this);
  }
}

obj.b(); // prints undefined, Window {...} (or the global object)
obj.c(); // prints 10, Object {...}