1. Что такое this и как он определяется при вызове
Что такое this и как он определяется при вызове
Зачем вообще нужен this
В JavaScript ключевое слово this — это контекст выполнения функции: значение, к которому функция может обратиться как к текущему объекту.
Главная особенность this в JavaScript:
this не привязан к функции навсегда.this определяется в момент вызова функции.Из-за этого одна и та же функция может работать с разным this, в зависимости от того, как её вызвали.
> "The value of this is determined by how a function is called (runtime binding)." — MDN Web Docs (this)
Что важно: где вызвали, а не где объявили
Многие ошибки с this появляются из-за ожидания, что this зависит от места, где написана функция. На самом деле решает call-site — точка вызова.
Рассмотрим одну и ту же функцию, вызванную разными способами:
Хотя show — одна и та же функция, this будет разным.
Четыре базовых правила определения this
Дальше мы разберём главные правила, по которым движок JavaScript выбирает значение this при вызове.
!Дерево решений, показывающее приоритет правил привязки this
Правило по умолчанию
Если функция вызывается просто по имени, без объекта слева и без специальных механизмов привязки, используется привязка по умолчанию.
В нестрогом режиме
В браузере this станет глобальным объектом window (в Node.js — глобальный объект global, но в разных средах детали могут отличаться).
В строгом режиме
В строгом режиме this будет undefined. Это полезнее, потому что ошибка проявится сразу.
Подробнее: MDN Web Docs (Strict mode).
Неявная привязка: вызов как метода объекта
Если функция вызывается как метод, то есть в форме obj.fn(), то this становится объектом слева от точки.
Важно: привязка зависит не от того, где функция лежит, а от того, как она вызвана.
Типичная ловушка: потеря контекста
Если метод вытащить и вызвать как обычную функцию, неявная привязка исчезает.
Причина: fn() — это уже обычный вызов, поэтому работает правило по умолчанию (в strict mode this === undefined).
Явная привязка: call, apply, bind
JavaScript позволяет установить this явно.
call
fn.call(thisArg, a, b, c) вызывает функцию сразу, подставляя this = thisArg.
apply
То же, что call, но аргументы передаются массивом.
bind
bind не вызывает функцию сразу. Он возвращает новую функцию с навсегда привязанным this.
Привязка через new: вызов как конструктора
Если функция вызывается с new, то создаётся новый объект, и this внутри функции указывает на этот новый объект.
Идея такая:
this внутри User становится этим объектомПриоритет правил (что “сильнее”)
Если кажется, что применимо несколько правил, нужно помнить приоритет.
new (конструктор) — самый высокий приоритетcall / apply), а также заранее привязанная функция через bindobj.fn())Практический вывод: чтобы понять this, всегда начинайте с поиска точки вызова и формы вызова.
Краткое резюме
| Как вызвали функцию | Пример | Каким будет this |
|---|---|---|
| Как конструктор | new F() | новый созданный объект |
| Явно указали | f.call(x) / f.apply(x) | x |
| Заранее привязали | const g = f.bind(x) | x |
| Как метод объекта | obj.f() | obj |
| Обычный вызов | f() | undefined в strict mode, иначе глобальный объект |
В следующих материалах курса обычно отдельно разбирают частые ловушки (потеря контекста при колбэках), а также особое поведение this у стрелочных функций и в классах.