0

I am making a Conway's Game of Life simulation in frontend. I create an object using an object constructor function. I am not done with the program. Currently, I use the object to create a table and assign each cell a css class for alive/dead. Eventually, it will also run the simulation.

I added a method to toggle the state of a cell by clicking on it. However, when I click on a cell, I would get an error in the debugger saying that such method does not exist. After playing around with it for a while, I think I reached the conclusion that "this" is not referring to the object of the object constructor function but maybe the cell that got clicked. Is this what is really happening? How can I access the parent method?

This is the offending code:

this.tableBody.addEventListener('click', function (cll) {
  const cell = cll.target.closest('td');
  if (!cell) { return }; //quit if didn't click on cell
  this.toggleState(cell.parentElement, cell.cellIndex);
});

Here is the full code:

function makeGame(rows = 5, columns = 10) {

  this.rows = rows;
  this.columns = columns;
  this.classAlive = 'alive';
  this.classDead = 'dead';
  this.table = document.createElement('table');
  this.tableBody = document.createElement('tbody');

  this.createTable = function () {

    for (let i = 0; i < this.rows; i++) {
      let row = document.createElement("tr");
      for (let j = 0; j < this.columns; j++) {
        let cell = document.createElement("td");
        cell.className = this.classDead;
        row.appendChild(cell);
      }
      this.tableBody.appendChild(row);
    }
    this.table.appendChild(this.tableBody);
    this.tableBody.addEventListener('click', function (cll) {
      const cell = cll.target.closest('td');
      if (!cell) { return }; //quit if didn't click on cell
      this.toggleState(cell.parentElement, cell.cellIndex);
    });
  }

  this.renderTable = function () {
    this.createTable();
    document.getElementById('lifes-bin').appendChild(this.table);
  }

  this.whatState = function (r, c) {
    return this.table.rows[r].cells[c].className;
  }

  this.setState = function (r, c, state) {
    this.table.rows[r].cells[c].className = state;
  }

  this.toggleState = function (r, c) {
    (this.whatState(r, c) == this.classDead) ? this.setState(r, c, this.classAlive) : this.setState(r, c, this.classDead);
  }
}


window.addEventListener('DOMContentLoaded', (event) => { startGame(); });

function startGame(r = 5, c = 10) {
  gameOfLife = new makeGame(r, c);
  gameOfLife.renderTable();
}

I've tried referencing the parent object as makeGame.toggleState but that doesn't work. I was expecting "this" to reference the object from the object constructor function. I recently created a dummy variable "papa = this;" before entering the offending code. Then I called papa.toggleState but I am assuming there is a "smarter" way.

pilchard
  • 12,414
  • 5
  • 11
  • 23
joe
  • 1

0 Answers0