Often when using a callback you want access to a specific context.
function SomeClass(msg, elem) {
  this.msg = msg;
  elem.addEventListener('click', function() {
    console.log(this.msg);  // <= will fail because "this" is undefined
  });
}
var s = new SomeClass("hello", someElement);
Use bind
bind effectively generates a new function that sets this to whatever
was passed to bind then calls the original function.
  function SomeClass(msg, elem) {
    this.msg = msg;
    elem.addEventListener('click', function() {
      console.log(this.msg);  
    }.bind(this));  // <=-  bind the function to `this`
  }
Use arrow functions
Arrow functions automatically bind the current this context.
  function SomeClass(msg, elem) {
    this.msg = msg;
    elem.addEventListener('click',() => {   // <=-  arrow function binds `this`
      console.log(this.msg);  
    });
  }
Often you'd like to call a member function, ideally passing any arguments that were passed to the event on to the function.
Use bind
  function SomeClass(msg, elem) {
    this.msg = msg;
    elem.addEventListener('click', this.handleClick.bind(this));
  }
  SomeClass.prototype.handleClick = function(event) {
    console.log(event.type, this.msg);
  };
Use arrow functions and the rest operator
  function SomeClass(msg, elem) {
    this.msg = msg;
    elem.addEventListener('click', (...a) => this.handleClick(...a));
  }
  SomeClass.prototype.handleClick = function(event) {
    console.log(event.type, this.msg);
  };
For DOM event listeners in particular you can implement the EventListener interface
  function SomeClass(msg, elem) {
    this.msg = msg;
    elem.addEventListener('click', this);
  }
  SomeClass.prototype.handleEvent = function(event) {
    var fn = this[event.type];
    if (fn) {
       fn.apply(this, arguments);
    }
  };
  
  SomeClass.prototype.click = function(event) {
    console.log(this.msg);
  };