JS Class 属性 "is undefined" 即使它似乎已被定义

JS Class property "is undefined" even tho it appears to be defined

我对 JS 很陌生,我正在尝试用自定义尺寸的棋盘做一个 TicTacToe 游戏,以尝试了解更多信息。我首先只编写了一个 3x3 版本,然后从那里开始构建。

就在加载页面和网格渲染后我已经过了输入自定义网格大小的位置时,我开始遇到同样的问题,当我试图点击任何单元格来尝试玩转弯时。

"this.game_state[clicked_cell_i] is undefined".

我已经尝试打开 F12 并检查 game_state 数组(这是一个二维字符串数组,用于跟踪播放哪个单元格和不播放哪个单元格)但是当我这样做时一切看起来都很正常并且数组打印出来没有问题。 (图片展示了在 4x4 网格中打印出 game_state 数组)https://i.stack.imgur.com/gV0pY.png

如果有人能向我解释发生了什么或什至更好,我将不胜感激 - 帮助我修复它。谢谢:)

代码:https://jsfiddle.net/z8649pxL


class game {
    status_display;
    is_game_active;
    curr_player;
    game_state;

    constructor() {
        this.status_display = document.querySelector('.status');
        this.is_game_active = true;
        this.curr_player = "X";
        this.game_state = matrix(rows, rows, "");
    }

    cell_played(clicked_cell, clicked_cell_i, clicked_cell_j){
        this.game_state[clicked_cell_i][clicked_cell_j] = this.curr_player;
        clicked_cell.innerHTML = this.curr_player;
        if(this.curr_player === "X"){
            document.getElementById((i*rows)+j).style.backgroundColor = "#ff6600";
        } else if(this.curr_player === "O"){
            document.getElementById((i*rows)+j).style.backgroundColor = "#33ccff";
        }
    }

    cell_click(clicked_cellEvent){
        debugger
        const clicked_cell = clicked_cellEvent.target;
        let clicked_cell_i = parseInt(clicked_cell.getAttribute('i'));
        let clicked_cell_j = parseInt(clicked_cell.getAttribute('j'));
        if(this.game_state[clicked_cell_i][clicked_cell_j] !== "" || !this.is_game_active) {
            return;
        }
        this.cell_played(clicked_cell, clicked_cell_i, clicked_cell_j);
        this.res_validation();
    }
};

let ex_game = new game();

function create_grid() {
    document.getElementById('hidestart').style.display = "none";
    var Container = document.getElementsByClassName("grid");
    Container.innerHTML = '';
    
    rows = prompt("n?");
    let i = 0, j = 0;
      
    document.documentElement.style.setProperty("--columns-row", rows);
    for (i = 0; i < rows ; i++) {
        for(j = 0; j < rows; j++){
            var div = document.createElement("div");
            div.className = "cell";
            div.id = (i*rows)+j;
            div.setAttribute("cell-index", (i*rows)+j);
            div.setAttribute("i", i);
            div.setAttribute("j", j);
            let wrapper = document.getElementsByClassName("grid");
            wrapper[0].appendChild(div);
        }
    }
    document.querySelectorAll('.cell').forEach(cell => cell.addEventListener('click', (e) => {
        ex_game.cell_click(e);
        e.stopPropagation();
    }));
    document.getElementById('hidestart').style.display = "block";
}

function matrix(rows, cols, defaultValue){
    var arr = [];
    // Creates all lines:
    for(var i=0; i < rows; i++){
        // Creates an empty line
        arr.push([]);
        // Adds cols to the empty line:
        arr[i].push(new Array(cols));
        for(var j=0; j < cols; j++){
          // Initializes:
          arr[i][j] = defaultValue;
        }
    }
    return arr;
}```

当你打电话时

new game()

调用了 class 的构造函数。 在该构造函数中,您调用 matrix 需要行的值。 但最初 class 没有任何价值。

所以状态在那个时间点没有被初始化。 这就是为什么当你使用数组时,它变得不确定。

因此,要解决此问题,您可以在从用户获取行后尝试获取 class game 的对象,并将该行传递到参数中调用 class.

的构造函数时
let ex_game = new game(rows);

然后使用这个参数调用函数矩阵。

编辑:

我已经查看了您的代码。 错误出在名为 cell_played 的方法中。你正在使用它不知道的 i 和 j 。请用以下行替换您的代码。这将解决您的错误。

  cell_played(clicked_cell, clicked_cell_i, clicked_cell_j){
      this.game_state[clicked_cell_i][clicked_cell_j] = this.curr_player;
        clicked_cell.innerHTML = this.curr_player;
        if(this.curr_player === "X"){
            document.getElementById((clicked_cell_i*rows)+clicked_cell_j).style.backgroundColor = "#ff6600";
        } else if(this.curr_player === "O"){
        document.getElementById((clicked_cell_i*rows)+clicked_cell_j).style.backgroundColor = "#33ccff";
        }
    }

并从构造函数中删除参数 rows 并在从用户那里获取行数后调用构造函数。

let ex_game

function create_grid() {
    /* document.getElementById('hidestart').style.display = "none" */
    var Container = document.getElementsByClassName("grid");
    Container.innerHTML = '';
    rows = prompt("n?");
    let i = 0, j = 0;
    ex_game= new game().........