"this" внутри обработчика событий из атрибута HTML

Мне казалось, что я хорошо понял ключевое слово this, пока не увидел этот код:

<body>
    <button onclick = "go()">clic1</button>

    <button id = "btn">clic2</button>

    <script>

        function go() {
            console.info(this);
        }

        var btn = document.getElementById("btn");
        btn.onclick = function() {
            console.info(this)
        }

    </script>
</body>

У меня есть HTML-документ с двумя кнопками, которые при нажатии делают то же самое: они регистрируют ключевое слово «this».

Я очень удивлен, что они не показывают такой же результат:

Для кнопки «clic1»: this = Window

Для кнопки «clic2»: this = объект кнопки с идентификатором «btn».

Есть ли этому объяснение?

Спасибо

github.com/getify/You-Dont-Know-JS
t3__rry 07.06.2018 15:39

Afaik, нажатие первой кнопки - это функция, которая выполняет eval("go()"), что приводит к тому, что go теряет контекст и возвращается к window в качестве контекста. Это одна из многих причин, почему встроенный код плох.

Chris G 07.06.2018 15:42
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
159
1

Ответы 1

TL; DR:

go - это нет обработчик события первой кнопки. Обработчик событий - это анонимная функция, созданная анализатором HTML. В примере сгенерированный обработчик просто случайно вызватьgo.


Код JavaScript, предоставленный в HTML для атрибута onEventName, компилируется в функцию формы

function(event) {
    // code written in the attribute value
}

Функции, сгенерированные синтаксическим анализатором таким образом, имеют довольно странную цепочку областей видимости, которая включает элемент, свойством которого является сгенерированный обработчик, любой внешний элемент form, внутри которого находится элемент, и, по крайней мере, объект document. Причины для цепочки областей видимости восходят к тому времени, когда DOM была стандартизирована. Более старые версии IE предоставляли window.event вместо параметра event.

Итак, первая кнопка

 <button onclick = "go()">clic1</button>

в текущих браузерах генерирует обработчик кнопки onclick как:

 function( event) {
     go()
 }
  • обработчик onclick - это функция, принимающая параметр event. Вызывается со значением кнопки this.
  • go - это обычный вызов функции - значение this вызывающей стороны не применялось. Вы можете, скажем, передать this в качестве параметра, вызвав go(this), если хотите.
  • go был объявлен с использованием ключевого слова function и по умолчанию имеет значение this глобального объекта.

Во втором примере вы обычно компилируете выражение анонимной функции (без использования анализатора HTML) и присоединяете его непосредственно ко второму элементу кнопки.

  • присоединенная функция вызывается с кнопкой в ​​качестве ее значения this, которое может быть записано в консоль.

  • присоединенная функция не имеет цепочки областей видимости wierdo.

Другие вопросы по теме