JavaScript содержит зарезервированное слово this, которое ссылается на что-то, зависящее от того, в какой части JavaScript кода оно находится.
В этой статье я собираюсь рассказать, что обозначает this в каждом случае на примерах.
В глобальном контексте
Что случится, если вы используете this в глобальном контексте (т.е. не внутри функции)?
console.log(this === window); // true
Вы можете протестировать это с помощью панели разработчика в браузере в консоли.
Здесь видно, что в глобальном контексте this ссылается на windowObject. Посмотрим на следующий пример и результат:
this.message = "Check this."; window.message = "Check this out."; console.log(this.message); // "Check this out." console.log(window.message); // "Check this out." console.log(message); // "Check this out."
Посмотреть код в действии можно здесь.
Итак, что здесь происходит? Вторая строка window.message переопределяет значение this.message. В результате в консоли мы получаем 3 сообщения «Check this out.».
This в контексте функции
Что случится, если использовать this в контексте функции?
В следующих примерах то, на что ссылается this зависит от мода using strict:
function checkThisOut () { console.log(this === window); // true console.log(this); // object global } checkThisOut();
Как видно из примера, this ссылается на windowObject в глобальном контексте. Теперь попробуем использовать strict мод:
function checkThisOut () { "use strict"; console.log(this === window); // false console.log(this); // undefined } checkThisOut();
Теперь this не ссылается на windowObject.
This в паттернах
Давайте посмотрим, как работает this в таком случае:
var s, PrimaryNameSpace = { settings : { first: true, second: false, foo: 'bar' }, init: function () { console.log(this); // ссылается на PrimaryNameSpace }, nextMethod: function () { }, anotherMethod: function () { } }; PrimaryNameSpace.init();
В данном контексте внутри любой функции this будет ссылаться на весь модуль. Фактически, если вы посмотрите на сообщение, созданное внутри метода init() при помощи инструментов разработчика, то вы увидите следующее:
Консоль показывает вам объект. Вы можете углубиться в объект для просмотра различных методов, а также значений.
Таким образом, внутри метода init() вы можете ссылаться на модуль и настройки, используя this, как показано ниже:
/* ... other code here ...*/ init: function () { s = this.settings; this.nextMethod(); this.anotherMethod(); console.log(s); }, /* ... other code here ...*/ PrimaryNameSpace.init();
Используя this мы можем ссылаться на другие методы в короткой форме. Пример ниже эквивалентен тому, что написано выше:
/* ... other code here ...*/ init: function () { s = PrimaryNameSpace.settings; PrimaryNameSpace.nextMethod(); PrimaryNameSpace.anotherMethod(); console.log(s); }, /* ... other code here ...*/
В обоих случаях будет следующее:
Что насчет вложенных функций?
Если у вас есть функция внутри одного из методов, тогда значение this изменится. И тогда через this нельзя будет получить доступ к объекту модуля:
/* ... other code here ...*/ init: function () { s = this.settings; (function () { this.nextMethod(); // [object Window] has no method 'nextMethod' })(); }, /* ... other code here ...*/
Необходимо будет использовать полную форму обращения, чтобы обратиться к функции: PrimaryNameSpace.nextMethod(), т.к. this теперь ссылается на глобальный window объект, а не на объект PrimaryNameSpace.
Если использовать мод using strict, то this будет undefuned.
Заключение
Данная статья показывает, что использование this может быть очень полезно. Но помните, что контекст может изменяться и тогда this будет ссылаться на другой объект.
Полезные ссылки:
Спасибо за внимание! Подписываемся на рассылку! 😉
Свои замечания, советы и отзывы пишите, пожалуйста, в комментариях.