Почему значение `this` в обратном вызове прослушивателя событий dom не является окном?

#javascript #html #object #ecmascript-6

#javascript #HTML #объект #ecmascript-6

Вопрос:

Давайте посмотрим на следующий код:

 const div = document.getElementById('foo');
div.addEventListener('click', function() {
  console.log(this);
});  
 <div id="foo">click me</div>  

Эта кнопка всегда будет регистрировать элемент dom, на который я нажимаю. Я всегда знал, что это правда, и я знаю, что могу использовать функцию со стрелкой здесь, чтобы получить значение this the window . Мы предполагаем, что для этого вопроса синтаксис функции, отличной от стрелки.

Насколько мне известно, значение this получает свое значение в зависимости от того, как вызывается заключающая функция. Обратный вызов этого прослушивателя событий, безусловно, не вызывается для элемента dom.

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

Если эта анонимная функция вызывается в глобальном контексте выполнения, не должно ли значение this быть window?

Что возвращает к вопросу заголовка, почему значение this в обратном вызове прослушивателя событий dom не является window ? (Предполагая, что обратный вызов не является функцией со стрелкой)

Ответ №1:

Это потому, что это метод, прикрепленный к div объекту — думайте об этом так:

 const div = {
    addEventListener: function(event, callback) {...}
};
  

В этом примере this будет ссылаться на div , как и следовало ожидать.

Это то, что на самом деле происходит в вашем коде, только определяется по-другому.

Комментарии:

1. интересно, значит, обратный вызов привязывается как свойство элемента dom?

2. Обратный вызов является анонимной функцией, и this в методе (если только вложенные объекты / функции со стрелками) будет ссылаться на родительский объект, так что да.

3. что заставляет меня задуматься об этом, так это то, как в основном работают setInterval и setTimeout . Несмотря на то, что эти методы определены в window , в этих обратных вызовах используется window as this , я всегда думал, что это потому, что когда обратные вызовы попадают в стек, они вызываются на глобальном уровне. Аналогично, разве обратные вызовы событий выполняются не таким же образом? Я думал, что это один и тот же контекст выполнения

Ответ №2:

Значение this в обработчике

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

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

Комментарии:

1. не могу поспорить с документами, похоже, что поведение обратного вызова события было бы похоже на поведение обратного вызова setTimeout или setInterval , но я думаю, что это не так