#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
asthis
, я всегда думал, что это потому, что когда обратные вызовы попадают в стек, они вызываются на глобальном уровне. Аналогично, разве обратные вызовы событий выполняются не таким же образом? Я думал, что это один и тот же контекст выполнения
Ответ №2:
Значение this в обработчике
Часто желательно ссылаться на элемент, для которого был запущен обработчик событий, например, при использовании универсального обработчика для набора похожих элементов.
При присоединении функции-обработчика к элементу с помощью
addEventListener()
, значение this внутри обработчика является ссылкой на элемент. Это то же самое, что значениеcurrentTarget
свойства аргумента события, которое передается обработчику.
Комментарии:
1. не могу поспорить с документами, похоже, что поведение обратного вызова события было бы похоже на поведение обратного вызова
setTimeout
илиsetInterval
, но я думаю, что это не так