Ключевое слово this в JavaScript
Слово this является одним из наиболее мощных ключевых слов JavaScript. Но могут возникнуть трудности с его использованием, если вы точно не знаете, как оно работает и где применяется.
В этой статье я расскажу, как использовать ключевое слово this в обработке событий.
Опытным программистам быть может данная статья не принесет никакой опльзы, но новичкам несомненно будет полезно ее изучить.
Владелец
Вопрос, который мы рассмотрим в этом пункте — это «К чему мы обращаемся через ключевое слово this в функции doSomething()»?
function doSomething() {
this.style.color = '#cc0000';
}
В JavaScript this всегда относится к «владельцу» выполняемой функции, или, если быть точнее, к объекту, методом которого является функция. Когда мы определяем нашу функцию doSomething() в глобальном пространстве, владельцем является страница или объект window (глобальный обект) JavaScript. Например, аттрибут «onclick» принадлежит тому элементу(объекту) HTML, к которому он относится.
Это «владение» — результат объектно-ориентированного подхода JavaScript.
------------ window -------------------------------------- | / \ | | | | | this | | ---------------- | | | | HTML element | <-- this ----------------- | | ---------------- | | doSomething() | | | | | ----------------- | | -------------------- | | | onclick property | | | -------------------- | | | ----------------------------------------------------------
Если мы напрямую выполним doSomething(), ключевое слово this будет относиться к окну, и функция попытается изменить style.color окна. Но так как у окна нет объекта style, функция завершается неудачей и вовзратит ошибку.
Копирование
Итак, для того, чтобы использовать this в полном объеме, нам нужно позаботится о том, чтобы «владельцем» функции, использующей this являлся правильный объект HTML. Например нам нужно скопировать функцию в наш аттрибут «onclick».
element.onclick = doSomething;
Функция полностью скопирована в аттрибут «onclick» (который теперь становится методом). Теперь при выполнении обработчика событий this относится к элементу HTML и его color поменяется.
------------ window -------------------------------------- | | | | | | | ---------------- | | | HTML element | <-- this ----------------- | | ---------------- | | doSomething() | | | | | ----------------- | | ----------------------- | | | |copy of doSomething()| <-- copy function | | ----------------------- | | | ----------------------------------------------------------
Конечно же мы можем скопировать функцию в несколько обработчиков событий сразу, будь то «onclick» или любые другие. Каждый раз this будет относиться к определенному элементу HTML:
------------ window -------------------------------------- | | | | | | | ---------------- | | | HTML element | <-- this ----------------- | | ---------------- | | doSomething() | | | | | ----------------- | | ----------------------- | | | |copy of doSomething()| <-- copy function | | ----------------------- | | | | | | ----------------------- | | | | another HTML element| <-- this | | | ----------------------- | | | | | | | | | ----------------------- | | | |copy of doSomething()| <-- copy function | | ----------------------- | | | ----------------------------------------------------------
Таким образом ключевое слово this используется наиболее эффективно. При каждом вызове функции, this относится к тому элементу HTML, который в этот момент обрабатывает событие, элемент HTML, «владеющий» копией doSomething().
Ссылки
Однако, если вы используете линейную регистрацию событий:
<element onclick="doSomething()">
Вы не делаете копии функции! Вместо этого вы обращаетесь к ней, и разница огромна! Аттрибут «onclick» не содержит саму функцию, а только ее вызов:
doSomething();
То есть он говорит «обратись к doSomething() и выполни ее». Обратившись к doSomething(), ключевое слово this относится к глобальному объекту window и функция возвращает сообщения об ошибках.
------------ window -------------------------------------- | / \ | | | | | this | | ---------------- | | | | HTML element | <-- this ----------------- | | ---------------- | | doSomething() | | | | | ----------------- | | ----------------------- / \ | | | go to doSomething() | | | | | and execute it | ---- reference to | | ----------------------- function | | | ----------------------------------------------------------
Разница
Если вы хотите использовать this для доступа к HTML элементу, обрабатывающему событие, вам нужно убедиться, что ключевое слово this написано именно в аттрибуте «onclick». Только в этом случае оно относится к тому элементу HTML, к которому преписан обработчик событий. То есть если вы выполните
element.onclick = doSomething;
alert(element.onclick)
то получите
function doSomething()
{
this.style.color = '#cc0000';
}
Как вы видите, ключевое слово this находится в методе «onclick()». Следовательно, оно относится к элементу HTML.
Но если вы выполните
<element onclick="doSomething()">
alert(element.onclick)
то получите
function onclick()
{
doSomething()
}
Это только ссылка на функцию doSomething(). Ключевое слово this не находится в методе «onclick» и поэтому не относится к элементу HTML.
Примеры — копирование
This записывается в метод «onclick» в следующих случаях:
element.onclick = doSomething
element.addEventListener('click',doSomething,false)
element.onclick = function () {this.style.color = '#cc0000';}
<element onclick="this.style.color = '#cc0000';">
Примеры — ссылки
В этих примерах this относится к окну:
element.onclick = function () {doSomething()}
element.attachEvent('onclick',doSomething)
<element onclick="doSomething()">
Заметьте наличие attachEvent(). Главная проблема модели регистрации событий Microsoft в том, что attachEvent() создает ссылку на функцию, а не копирует ее. Поэтому иногда невохможно узнать, какой объект HTML в данный момент обрабатывает событие.
Комбинации
При использовании линейной регистрации событий вы также можете пересылать this в функцию, то есть вы все еще можете использовать его:
<element onclick="doSomething(this)">
function doSomething(obj) {
obj.style.color = '#cc0000';
}
Английский вариант статьи: The this keyword
Спонсор поста: Агентство «Web++» — продвижение и создание сайтов в Волгограде.
Похожие темы
RSS-лента комментариев к этой статье | Обратная ссылка (trackback link)



>> В JavaScript this всегда относится к «владельцу» выполняемой функции, или, если быть точнее, к объекту, методом которого является функция.
Особенность использования «
this» в «JavaScript» заключается в том, что ссылка на объект «this», в контексте которого вызывается функция, может меняться динамически и не всегда указывать на объект, методом которого является данная функция. Другими словами: «„Владелец“ (объект, методом которого является функция) — не всегда контекст вызова функции (this)».В метод «
addEventListener» тоже передается ссылка на функцию, и не происходит никакого копирования, просто функция вызывается в контексте объекта, к которому «привязана», в отличие от модели обработки событий, предлагаемой «Microsoft».Octane, хороший комментарий!
Продолжая комментарий Octane. Возможно явное указание контекста для вызываемой функции с помощью методов apply и call класса Function:
Octane, спасибо за разъяснения. меня смущало это «копирование»