Ключевое слово this в JavaScript

VitaliyRodnenko, 31.10.2008

Слово 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 рассылку или рассылку по электронной почте. Так же вы можете следить за нами в Twitter.

Категории: JavaScript, Переводы | Комментировать

Комментарии (8)

  1. Octane / 31.10.2008 в 19:25

    >> В JavaScript this всегда относится к «владельцу» выполняемой функции, или, если быть точнее, к объекту, методом которого является функция.

    Особенность использования «this» в «JavaScript» заключается в том, что ссылка на объект «this», в контексте которого вызывается функция, может меняться динамически и не всегда указывать на объект, методом которого является данная функция. Другими словами: «„Владелец“ (объект, методом которого является функция) — не всегда контекст вызова функции (this)».

    В метод «addEventListener» тоже передается ссылка на функцию, и не происходит никакого копирования, просто функция вызывается в контексте объекта, к которому «привязана», в отличие от модели обработки событий, предлагаемой «Microsoft».

  2. Интернет-консультант / 08.12.2008 в 21:22

    Octane, хороший комментарий!

  3. Suor / 23.12.2008 в 08:20

    Продолжая комментарий Octane. Возможно явное указание контекста для вызываемой функции с помощью методов apply и call класса Function:

    function doSomething() {
    	this.style.color = '#cc0000';
    }
  4. den / 19.03.2009 в 14:14

    Octane, спасибо за разъяснения. меня смущало это «копирование»

  5. Amir / 13.08.2011 в 20:17

    Как-то вы код не расписали нормально, или я не понял. Например, что значит конструкция типа element.onclick = doSomething? Как это может работать? Я новичок в программировании и не до конца прописанное не очень понимаю. Может вы это имели в виду:

    ???

    Иначе, не могу впитать как можно обратиться к ‘this’. Распишите пожалуйста, если вам не трудно!!

  6. Amir / 13.08.2011 в 20:20

    что-то код мой пропал. напишу без скобок: element onclick = «this.style.color = ‘#cc0000′ «

  7. Дмитрий / 09.05.2012 в 15:58

    Я разобрался с этим this тут http://wseoweb.narod.ru/js/19.htm. Там пример нормальный дан, а то тут, без хороших примеров не каждый поймет

  8. Кирилл / 12.01.2013 в 11:45

    Octane. А пример того что вы сказали?

Оставить комментарий

480×60
480×60