Доброго времени суток, друзья!
В нашем прошлом уроке мы c Вами рассмотрели возможности JavaScript для манипулирования непосредственно стилевого представления нужных нам html-элементов, мы познакомились с объектом Style, со способами доступа к этому объекту, а также со способами доступа к нужным нам свойствам представления. Помимо этого, мы узнали, как в JavaScript'e формируются названия стилей, состоящих более чем из одного слова и разобрали несколько примеров на практике.
Во всех наших предыдущих уроках, где мы рассматриваем и описываем способы манипуляции Объектами (Objects), Cобытиями (Events), Функциями (Functions) не хватает одной важной детали, которая всегда присутствует в работе со всеми вышеперечисленными сущностями. Я специально не описывал её раньше, хотя для программирования на JavaScript'e эта "деталь" играет важную роль. С моей точки зрения прежде всего надо было разобрать сами сущности, где эта "деталь" может присутствовать, а уже после этого рассматривать нюансы ее работы. Речь идет о встроенной переменной this, которую часто называют контекстом или указателем.
В нашем сегодняшнем уроке мы рассмотрим основные аспекты поведения этой переменной. Однако такую тему как переменная this невозможно рассмотреть без темы глобальная и локальная область видимости. Поэтому мы будем рассматривать эти темы параллельно.
Урок 28. Встроенная переменная this. Глобальная и локальная области видимости.
Вообще тема переменной this в среде JavaScript-разработчиков муссируется в основном из-за новичков, для которых работа с ней часто оказывает совсем неясной, или неясной до конца. Ну а так как в повседневной разработке мы очень часто имеем дело с this то понимание её работы должно быть стопроцентным. Но давайте по порядку. Итак, что же из себя представляет это пресловутый **this (контекст, указатель) **?
Во-первых, this - это переменная, что уже говорит нам о том, что ее значение может меняться.
Во-вторых, this - это контекст или указатель, что говорит нам о том, что эта переменная всегда будет указывать на что-либо. И вот на что именно эта переменная будет указывать мы и постараемся выяснить в сегодняшнем уроке. Именно эта часть зачастую вызывает у новичков вопросы, хотя на самом деле в ней нет ничего сложного.
Существует всего пять вариантов в зависимости, от которых переменная this будет менять свое значение. Эти пять вариантов и соответственно значение переменной this в рамках этих вариантов надо просто запомнить:
- Вызов переменной this в глобальной области видимости.
- Вызов переменной this внутри функции (Function).
- Вызов переменной this внутри метода объекта (Object).
- Переопределение переменной this.
- Вызов переменной this внутри конструктора.
Мы с Вами рассмотри четыре пункта из этого списка. А к последнему (пятому) пункту вернемся, когда познакомимся с работой конструктора в JavaScript'e.
Вызов переменной this в глобальная область видимости.
Из предыдущих уроков мы с Вами знакомы с такими терминами, как Глобальные переменные и Глобальные объекты. Это те переменные и те объекты к которым мы можем обращаться из любого места в нашем коде, те самые доступ к которым мы моем получить используя всего одну точку главного объекта window (Урок 24). А что означает глобальная область видимости для переменной this? Это область видимости нашего объекта window. Как мы знаем из предыдущих уроков этот объект главный в иерархии встроенных объектов JavaScript. Он является вершиной иерархической пирамиды и как бы "обволакивает" собой все что находится в нашем коде. Когда мы создаем переменную или именованную функцию, то переменная сразу же становится свойством объекта window, а функция его методом. Из этого следует что как только мы открываем наш документ, в котором собираемся писать JavaScript код мы сразу же попадаем в глобальную область видимости нашего объекта window. Другими словами, если мы обращаемся к this на том же уровне вложенности, на котором при создании переменной или именованной функции они сразу же становятся свойством или методом объекта window, то мы обращаемся в глобальной области видимости. Приведем пример:
/* Переменная this */
var a = 5;
function message(text) {
alert(text);
}
this;
Обратите внимание на код сверху. Наша переменная a
создана таким образом, что она сразу же становится свойством window и может быть доступна как window.a
. На этом же уровне создана именованная функция message
, которая сразу становится методом и доступ к ней можно получить, используя window.message
. Весь этот код находится в глобальной области видимости. В нем создаются Глобальные переменные и Глобальные функции. Соответственно обращение к переменной this (такое как на строке №9) также осуществляется в глобальной области видимости. Её значение в этом случае всегда будет указывать на объект window.
Переменная this всегда будет содержать в своем значении ссылку на глобальный объект window если обратиться к ней в глобальной области видимости.
Как нам проверить что это действительно так? Ведь по сути код вверху конечно отработает, но визуально в браузере нам ничего не отобразит. Однако нам может помочь инструмент профилирования кода - вкладка Console. Давайте откроем браузер с нашим index.html где отработал код из нашего примера и обратимся к профилированию.
Как видим, значение переменной this вызванной на том же уровне, где переменная a
становится свойством window а функция message
- методом, будет равно самому объекту window.
Вызов переменной this внутри функции (Function).
Функции в JavaScript'e имеют одну очень важную особенность. При этом какая именно функция используется в данный момент (именованная, анонимная или самовызывающаяся) абсолютно не важно. Код который мы описываем внутри функции уже не воспринимается как код в глобальной области видимости. Он попадает в область видимости функции, в которой мы работаем. Пример:
function message(text) {
var a = 5;
}
Обратите внимание, мы перенесли создание переменной a
внутрь функции message
и теперь в отличие от предыдущего примера обращение window.a
вернет нам undefined. То есть переменная a
более не находится в глобальной области видимости, а перенеслась в область видимости функции. Такую область видимости называют локальной. Чтобы убедится в том, что внутри функции переменная, а существует можно немного преобразовать код примера и выполнить его в браузере:
function message(text) {
var a = 5;
alert(a)
}
message();
alert(window.a);
Как видим обращение к переменной a
внутри функции message
используя конструкцию alert
подтверждает наши слова. Внутри функции эта переменная существует в том время как в глобальной области видимости ее по-прежнему нет.
Возвращаясь к переменной this требуется понимать, что если мы обращаемся к ней внутри функции (опять же не важно какой) то ее значение по прежнему будет указывать на глобальный объект window. Проверим:
function message(text) {
var a = 5;
alert(this);
}
message();
Обратите внимание что мы обращаемся к переменной this функции message
. И если мы проверим результат выполнения этого кода в браузере мы увидим, что...
...значение переменной this в этом случает также будет ссылаться на объект window.
Вызов переменной this внутри метода объекта (Object).
Из предыдущих уроков мы помним, что метод объекта — это тоже функция. И по своей сути обращение к переменной this внутри метода так же будет обращение внутри функции, однако значение this при таком вызове поменяется. И будет оно указывать на Объект, метод которого мы используем в данный отрезок времени. Давайте проверим на практике.
var a = 5;
function getGlobalA(){
alert(this.a);
}
var obj = {
a: 3,
getLocalA: function() {
alert(this.a)
}
}
getGlobalA();
obj.getLocalA();
Очень содержательный пример как по мне. Обратите внимание мы создали переменную a
со значением «5» в глобальной области видимости. Мы знаем, что она сразу же стала свойством объекта window и мы можем достучатся к ней через запись window.a
. далее мы создаем функцию getGlobalA
. Мы уже знаем что при обращении к this внутри функции эта переменная будет ссылаться на window, то есть запись alert(this.a);
внутри неё будет по своему смфслу равна записи alert(window.a)
И после вызова этой функции мы должны получить сообщение с текстом "5". А вот далее мы создали объект obj
который добавили свойство a
и метод getLocalA
. Внутри метода мы видим конструкцию alert(this.a)
которая по своему визуальному представлению одинакова конструкции из функции getGlobalA
. Однако несмотря на то, что внешне эти конструкции одинаковы, значение переменной this в них будет разным. И если мы вызовем getLocalA
как метод объекта obj
, то ссылаться эта переменная будет на window а на сам объект obj. Поэтому текст второго сообщения будет равен "3". Давайте проверим в браузере:
Как видим, результат такой как мы и ожидали.
А на сегодня все.
Ссылки на предыдущие уроки:
Урок 1 - Окружение.,
Урок 2 - Некоторые особенности синтаксиса.,
Урок 3 - Переменные.,
Урок 4 - Типы переменных, как основа для их взаимодействия.,
Урок 5 - Операции с переменными одного типа.,
Урок 6 - Операции с переменными одного типа. Часть II.,
Урок 7 - Взаимодействие переменных с разными типами.,
Урок 8 - Взаимодействие переменных разного типа. часть II.,
Урок 9 - Взаимодействие переменных разного типа. Часть III.,
Урок 10 - Другие возможные взаимодействия между переменными.,
Урок 11 - Другие возможные взаимодействия между переменными. Часть II.,
Урок 12 - Другие возможные взаимодействия между переменными. Операторы присваивания.,
Урок 13 - Другие возможные взаимодействия между переменными. Операторы сравнения.,
Урок 14 - Сложные переменные. Array и Object.,
Урок 15 - Условные операторы.),
Урок 16 - Циклы.,
Урок 17 - Циклы. Часть II.,
Урок 18 - Функции.,
Урок 19 - Функции. Часть II.,
Урок 20 - Профилирование. Функции, часть III.,
Урок 21 - Функции, Часть IV. Аргументы.,
Урок 22 - Objects (Объекты).,
Урок 23 - Встроенные функции и объекты.,
Урок 24 - Встроенные функции и Объекты, Часть II. Глобальные функции и переменные.,
Урок 25 - Встроенные функции и Объекты, Часть III. Document Object Model.,
Урок 26 - Встроенные функции и Объекты, Часть III. Document Object Model.
Урок 27 - Встроенные объекты. Объект Style, Events, Часть II.
@rassen, Поздравляю!
Ваш пост был упомянут в моем хит-параде в следующей категории:
Интересно, сколько человек в Голосе уже стали программистами?)
Главное что возможность есть
Good job and good luck @rassen
thank you
You're welcome