Методы и this
Здесь будет встроен видео-разбор темы (5–7 минут, YouTube / RuTube / VK Видео) — тем, кто лучше воспринимает на слух, текст ниже не обязателен.
До сих пор наши объекты только хранили данные. Пора научить их действовать: разберёмся, что такое методы и как ключевое слово this помогает методу дотянуться до своего объекта.
Объекты в JavaScript описывают реальные сущности, а сущности не только «какие-то» — они ещё и что-то делают: пользователь здоровается, корзина считает сумму, таймер тикает. Действие описывается функцией, записанной в свойство объекта. Такая функция называется методом.
Писать sayHi: function() {} каждый раз необязательно — есть короткая запись: имя, скобки, тело. Работает так же, а читается легче, поэтому в реальном коде методы почти всегда пишут именно так.
Метод редко живёт сам по себе — обычно ему нужны данные родного объекта: поздороваться по имени, прибавить к своему счёту. Для этого внутри метода доступно ключевое слово this — ссылка на объект, у которого метод вызвали.
Можно ли написать user.name вместо this.name? Технически да, но это хрупко: если объект скопируют в другую переменную, а user перезапишут чем-то другим, метод потянется не туда. this же всегда указывает на «текущего хозяина» — объект, у которого метод вызвали прямо сейчас.
Главный сюрприз this: его значение определяется не там, где функция написана, а в момент вызова. Правило простое: this — это объект «перед точкой». Одна и та же функция в разных объектах будет работать с разными данными.
this = тот, кто стоит перед точкой в момент вызова
Метод можно даже «одолжить» у соседнего объекта — и this послушно переключится на нового хозяина.
Раз this — это «объект перед точкой», то без точки его нет. Сохраните метод в отдельную переменную, вызовите как обычную функцию — и связь с объектом порвётся.
Это частая ловушка при передаче методов в колбэки. Лекарство — привязка через bind; ему посвящена статья «call, apply и bind» в главе «this и контекст».
У стрелочных функций () => {} собственного this нет вовсе: встретив this внутри стрелки, JavaScript возьмёт его из окружающего кода. Поэтому стрелка — плохой кандидат на роль метода объекта, зато отличный помощник внутри метода: в колбэке она не потеряет this внешней функции. Подробности — впереди, в статье «Стрелочные функции и this».
- Метод — это функция в свойстве объекта; короткая запись —
sayHi() { ... }. thisвнутри метода — объект «перед точкой» в момент вызова.- Одна и та же функция в разных объектах получает разный
this. - Метод, вызванный без объекта (просто как функция), теряет
this. - У стрелочных функций своего
thisнет — они берут его из внешнего кода.
1/3Внутри метода show() объекта pen написано console.log(this.color). Чем будет this при вызове pen.show()?
2/3Метод скопировали: b.who = a.who. У объекта a имя «A», у b — «B». Что выведет b.who(), если метод печатает this.name?
3/3Когда JavaScript определяет значение this в обычной (не стрелочной) функции?
Представься сам
Добавьте объекту player метод greet, который выводит «Привет, Мария!». Имя нельзя писать в строке напрямую — метод должен брать его из объекта через this, чтобы работать с любым именем.
Добавьте метод greet() { console.log(`Привет, ${this.name}!`); }. Внутри метода this — это сам player, поэтому при смене имени в объекте приветствие обновится само.
Счётчик
Допишите объекту counter два метода: up() увеличивает value на единицу, show() печатает текущее значение. После двух вызовов up() метод show() должен вывести 2.
up() { this.value++; } и show() { console.log(this.value); }. Оба метода обращаются к одному и тому же объекту через this, поэтому значение накапливается между вызовами.