Вот версия es6:

ение многих лет я сталкивался с проблемами, пытаясь удалить прослушиватель событий в JavaScript. Часто мне приходится создавать независимую функцию в качестве обработчика. Но это просто небрежно и, особенно с добавлением функций стрелок, просто боль.

Я не после разового решения. Это должно работать во всех ситуациях независимо от того, КАК определен обратный вызов. И это должен быть сырой JS, чтобы любой мог его использовать.

Следующий код работает нормально, так как функцияclickHandler является уникальной функцией и может использоваться какaddEventListener а такжеremoveEventListener:

Этот пример был обновлен, чтобы показать, с чем я столкнулся в прошлом

const btnTest = document.getElementById('test');
let rel = null;

function clickHandler() {
  console.info('Clicked on test');
}

function add() {
  if (rel === null) {
    rel = btnTest.addEventListener('click', clickHandler);
  }
}

function remove() {
    btnTest.removeEventListener('click', clickHandler);
}

[...document.querySelectorAll('[cmd]')].forEach(
  el => {
    const cmd = el.getAttribute('cmd');
    if (typeof window[cmd] === 'function') {
      el.addEventListener('click', window[cmd]);
    }
  }
);
<button cmd="add">Add</button>
<button cmd="remove">Remove</button>
<button id="test">Test</button>

Раньше вы могли сделать это сarguments.callee:

var el = document.querySelector('#myButton');

el.addEventListener('click', function () {
  console.log('clicked');
  el.removeEventListener('click', arguments.callee); //<-- will not work
});
<button id="myButton">Click</button>

Но использование функции со стрелкой не работает:

var el = document.querySelector('#myButton');

el.addEventListener('click', () => {
  console.log('clicked');
  el.removeEventListener('click', arguments.callee); //<-- will not work
});
<button id="myButton">Click</button>

Есть ли способ лучше??

ОБНОВИТЬ

Как заявил @Jonas Wilms, этот способ будет работать:

 var el = document.querySelector('#myButton');

 el.addEventListener('click', function handler() {
   console.log('clicked');
   el.removeEventListener('click', handler); //<-- will work
 });
<button id="myButton">Click</button>

Если не Вам необходимо использовать привязку:

var obj = {
  setup() {
    var el = document.querySelector('#myButton');

    el.addEventListener('click', (function handler() {
      console.log('clicked', Object.keys(this));
      el.removeEventListener('click', handler); //<-- will work
    }).bind(this));
  }
}

obj.setup();
<button id="myButton">Click</button>

Проблема в том, что существует слишком много способов предоставить обработчик событий дляaddEventListener функция и ваш код может сломаться, если способ, которым вы передаете функцию, изменяется в рефакторе.

Ответы на вопрос(3)

Ваш ответ на вопрос