2

Я столкнулся с такой вот ситуацией и в образовательных целях интересно понять как это работает.

Я присвоил this.button.addEventListener переменной addHandler и вызов addHandler несколько раз привел к тому, что при нажатии на любое место документа срабатывают события, которые я с помощью этой конструкции повесил.

Почему это работает именно так, я не могу понять. Подскажите.

class Button1 {
  constructor(button, value) {
    this.button = button;
    this.value = value;
this.init();

}

init() { this.button.addEventListener('click', () => { console.log(this.value) }) } }

class Button2 { constructor(button, value) { this.button = button; this.value = value;

this.init();

}

init() { let addHandler = this.button.addEventListener; addHandler('click', () => { console.log(this.value) }) } }

let button1 = document.getElementById('button_1'); let button2 = document.getElementById('button_2'); let button3 = document.getElementById('button_3'); let button4 = document.getElementById('button_4'); let button5 = document.getElementById('button_5'); let button6 = document.getElementById('button_6');

let newButton1 = new Button1(button1, 'п'); let newButton2 = new Button1(button2, 'а'); let newButton3 = new Button1(button3, 'в'); let newButton4 = new Button2(button4, 1); let newButton5 = new Button2(button5, 2); let newButton6 = new Button2(button6, 3);

<p>Я думал сработает только событие кнопки, но срабатывает событие кнопки + события трех следующих кнопок. К тому же события трех кнопок срабатывае при клике на любом месте документа</p>
<button id='button_1'>п</button>
<button id='button_2'>а</button>
<button id='button_3'>в</button>
<p>При нажатии на одну, сработает функция всех</p>
<button id='button_4'>1'</button>
<button id='button_5'>2'</button>
<button id='button_6'>3'</button>
Igor
  • 1,211
  • Вопрос вообще не подразумевал, что он как-то связан с контекстом вызова. Почему всегда если вопрос хоть как-то В ИТОГЕ ОКАЗЫВАЕТСЯ связан с контекстом вызова, его пытаются отметить как дубликат? – Igor Apr 26 '18 at 13:30
  • Я думал, что я присваиваю метод данного конкретного объекта, а в итоге оказалось, что я присвоил переменной метод, который не привязан к конкретному объекту. Ответ в том, что я присваиваю универсальный метод, а не метод конкретного объекта. В итоге решается это с помощью контекста, но изначально вопрос не о том как не потерять контекст – Igor Apr 26 '18 at 13:34
  • Но ответ - о том :). Метод все равно привязан к конкретному объекту. Только объект специальный - window. –  Apr 26 '18 at 13:36

1 Answers1

1

Потому что вызов

addHandler('click', () => { ...

приводит к выполнению функции addHandler/addEventListener в глобальном контексте. То есть Button2.init навешивает обработчик клика на весь документ - три раза в Вашем примере. И они все выполняются на клик в любом месте окна.

Сравните:

  init() {
    let addHandler = this.button.addEventListener.bind(this.button);
    addHandler('click', () => { ...