Мне казалось, что я хорошо понял ключевое слово 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».
Есть ли этому объяснение?
Спасибо
Afaik, нажатие первой кнопки - это функция, которая выполняет eval("go()"), что приводит к тому, что go теряет контекст и возвращается к window в качестве контекста. Это одна из многих причин, почему встроенный код плох.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


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()
}
event. Вызывается со значением кнопки this.go - это обычный вызов функции - значение this вызывающей стороны не применялось. Вы можете, скажем, передать this в качестве параметра, вызвав go(this), если хотите.go был объявлен с использованием ключевого слова function и по умолчанию имеет значение this глобального объекта.Во втором примере вы обычно компилируете выражение анонимной функции (без использования анализатора HTML) и присоединяете его непосредственно ко второму элементу кнопки.
присоединенная функция вызывается с кнопкой в качестве ее значения this, которое может быть записано в консоль.
присоединенная функция не имеет цепочки областей видимости wierdo.