How to remove reference of a class object in JavaScript?

Viewed 139
document.addEventListener("DOMContentLoaded", () => {
  document.querySelector('start'),addEventListener('click', () =>{
    var car = new Car('Audi');
    document.addEventListener('keyup', e=>{
      car.printName();
    })
  })
})

class Car{
  constructor(name){
    this.name = name
  }

  printName(){
    console.log(this.name)
  }
}

I am trying to create a simple game using JavaScript OOP. After the DOM loads and the player hits the 'start' button, a new Car object is created by passing the object's name property. For simplicity, the only method in the class for now is 'printName' which prints.

The problem is the previous object remains in the memory even though the game should reset whenever the player hits start button, since I have created a brand new object.

Notice, in the above code, whenever a player hits 'start' button two times and presses any key, the 'printName' method gets invoked for both new and old object. How can I tackle this problem?

2 Answers

The problem here is that on every click of the start button you are creating a new keyup event listener because you are passing an anonymous (new) function.

To solve the issue, instead of an anonymous function you can pass a regular function into the keyup listener and add the var car declaration outside of the start click listener so that car becomes a global variable. Because the regular function (doSomething() below) always has the same address a new event listener won't be assigned on every click of the start button.

Another solution would be to move the onkeyup event listener declaration outside of the start click listener, but then it would not be tied to pressing the start button.

Check below:

document.addEventListener("DOMContentLoaded", () => {
  var car;
  document.getElementById('start').addEventListener('click', () =>{
    car = new Car('Audi');
    document.addEventListener('keyup', doSomething);  // gets assigned only once
    document.addEventListener('keyup', () => {        // gets assigned every time
        console.log("BMW");
    });
  });

  // gets assigned once, after DOM loads, but is not tied to the start button
  document.addEventListener('keyup', () => {   
    console.log("PORSCHE");
  });
  
  function doSomething() {
    car.printName();
  }
});


class Car{

  constructor(name){
    this.name = name
  }

  printName(){
    console.log(this.name)
  }
}
<input type="button" id="start" value="Start"/>

You can fix this issue by adding the keyup event outside the click event, so that the click event stops adding multiple keyup event listener to the stack like:

document.addEventListener("DOMContentLoaded", () => {
  var car;
  document.querySelector('start'), addEventListener('click', () => {
    car = new Car('Audi');
  })

  var handleKeyup = () => car && car.printName();
  document.addEventListener('keyup', handleKeyup, false)
})

class Car {
  constructor(name) {
    this.name = name
  }
  printName() {
    console.log(this.name)
  }
}
<button class="start">Start</button>

Related