front-end
August 9, 2020

Потужна роль THIS в JavaScript

09.08.20. ⏰- 8 хв

"This" вказує на об'єкт, а ось на який саме — вже залежить від контексту. Якщо використовувати "this" в глобальному контексті, він вкаже на window, а якщо розмістити всередині об'єкта — вкаже на цей об'єкт. Одним словом, це те, що бентежить початківців, а особливо тих, хто не має бекграунду в програмуванні. Давайте сьогодні це виправимо!

Що таке THIS?

Ось неофіційне, але дуже просте визначення:
"This" — це ключове слово, яке використовується в JavaScript та має особливе значення в залежності від контексту, в якому використовується. Причина чому "this" настільки зводить з пантелику на старті вивчення JavaScript, в тому, що контекст "this" змінюється в залежності від способу його використання.

Класно пояснює залежність від контексту уривок зі статті Раяна Мора:

Контекст — завжди є значенням ключового слова "this", яке є посиланням на об'єкт, що "володіє" кодом, який виконується цієї миті.

Отже, коли ми хочемо використовувати ключове слово "this", ми використовуємо його для посилання на ОБ'ЄКТ. Але який об’єкт?

Давайте розглянемо кілька прикладів:

  1. Коли "this" вказує на об'єкт Window (глобальний)
  2. Методи на об’єктах
    Коли "this" використовується як метод на об'єкті
    Коли "this" використовується як метод на вкладеному об'єкті
    Коли "this" використовується як метод на об'єкті (arrow functions - стрілкові функції)
  3. Контексти функцій
  4. Створення примірників об'єкта з функції конструктора за допомогою "нового" ключового слова

1. Коли "це" вказує на об'єкт Window

Якщо Ви спробуєте посилатися на "this" поза функцією, воно буде посилатися на контекст GLOBAL (наприклад, об'єкт Window у браузері).

Функції, що знаходяться в глобальному контексті (а не як метод на об'єкті), спрямовують ключове слово "this" назад на об'єкт Window.


2. Вкладені об'єкти

Значення "this" може стати більш заплутаним через вкладення в об'єктах.
Завжди Ваш об'єкт вкладається в інший об'єкт, а потім "this" вказує на об'єкт, для якого визначено метод.

Наприклад:

*Так, стоп! Але ж arrow functions є ЦІЛКОМ різні.

Ноуп. Це не жарт.

Якщо Ви використовуєте "this" як метод всередині об'єкта, то ключове слово "this" присвоюється цьому об'єкту. Але arrow functions так не працюють!

Натомість "this" буде вказувати на об'єкт Window або глобальний контекст.

Спробуйте самі:

Згідно з MDN:

Arrow functions мають коротший синтаксис ніж іменовані, тобто звичайні функції. Але вони не мають посилання на себе, тобто this, arguments, super чи new.target. Стрілочні функції не підходять для оголошення методів чи для використання як конструктор.


Тож слухайте експертів і не використовуйте функції стрілок як методи на Ваших об’єктах!


3. Коли "це" використовується у звичайному контексті функції:

Коли функція знаходиться в глобальній області, значенням "this" є об'єкт Window. Розгляньте це, ніби тестова функція є методом у контексті, в якому вона знаходиться (the window object).

Отже, логічно, що "this" буде вказувати на об'єкт Window.

Наприклад:

Однак якщо функція виконується в строгому режимі, "this" повернеться невизначеним, оскільки строгий режим не дозволяє прив'язку за замовчуванням.

Тому пам’ятайте: якщо Ви хочете використовувати "this" в строгому режимі, воно повинне бути визначене контекстом виконання, оскільки автоматично не приєднується до жодного об'єкта (навіть до об'єкта Window).

Коли "this" викликається з функції, оголошеної поза об'єктом:

Ви можете призначити властивість об'єкту та призначити його функції chase ().

Змінна 'dog' не матиме жодних методів ... поки не створити dog.foo і не призначити її функції chase ().

Далі викликати новий метод foo (який викликає chase () для виконання).

Значення "this" всередині chase () вказують на об'єкт "dog", який викликав функцію.

Але chase () спочатку мусить бути призначений об'єкту, а тоді вже викликаний. Інакше повернеться невизначеним.

У цьому контексті функція chase () повертається невизначеною, оскільки при запуску в глобальному контексті — "this" вказує на об'єкт вікна за замовчуванням і не має властивостей, визначених для цього об'єкта.


4. Ключове слово "New" і чому "This" настільки важливе

Корисно використовувати ключове слово "this" при створенні constructor functions для об'єктів, оскільки це уможливлює роботу методу на будь-якому об'єкті.

Constructor function дозволяє нам визначити об'єкт (наприклад, число чи рядок, але за винятком того, що він має свої особливі властивості та методи).

Важливо зауважити, що "this" не має значення у constructor function.

Однак кожного разу, коли Ви будете створювати новий екземпляр об'єкта Dog, значення "this" вказуватиме на об'єкт, який Ви тільки що створили. Він НЕ вказуватиме на сам прототип собаки.

Використовуйте ключове слово "new" з назвою типу об'єкта та передавайте будь-які необхідні параметри при ініціації нового екземпляра об'єкта.

Висновок

Є ще один спосіб, як "this" може отримати значення в JavaScript. За допомогою call, apply, and bind (викликати, застосувати та прив'язати).

Ми не додаємо до статті, тому що це викличе у Вас ще більше плутанини навколо "this", поки не зрозумієте об'єкти глибше.

Щоб усвідомити концепцію, Вам знадобиться певний час, але найбільш корисно весь час продовжувати читати та практикувати.

Прийде час, коли все нарешті стане ясно!