Методы и this

объекты≈ 6 минут

Здесь будет встроен видео-разбор темы (5–7 минут, YouTube / RuTube / VK Видео) — тем, кто лучше воспринимает на слух, текст ниже не обязателен.

До сих пор наши объекты только хранили данные. Пора научить их действовать: разберёмся, что такое методы и как ключевое слово this помогает методу дотянуться до своего объекта.

Разделы темы:·

Объекты в JavaScript описывают реальные сущности, а сущности не только «какие-то» — они ещё и что-то делают: пользователь здоровается, корзина считает сумму, таймер тикает. Действие описывается функцией, записанной в свойство объекта. Такая функция называется методом.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Писать sayHi: function() {} каждый раз необязательно — есть короткая запись: имя, скобки, тело. Работает так же, а читается легче, поэтому в реальном коде методы почти всегда пишут именно так.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Метод редко живёт сам по себе — обычно ему нужны данные родного объекта: поздороваться по имени, прибавить к своему счёту. Для этого внутри метода доступно ключевое слово this — ссылка на объект, у которого метод вызвали.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Можно ли написать user.name вместо this.name? Технически да, но это хрупко: если объект скопируют в другую переменную, а user перезапишут чем-то другим, метод потянется не туда. this же всегда указывает на «текущего хозяина» — объект, у которого метод вызвали прямо сейчас.

Главный сюрприз this: его значение определяется не там, где функция написана, а в момент вызова. Правило простое: this — это объект «перед точкой». Одна и та же функция в разных объектах будет работать с разными данными.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

this = тот, кто стоит перед точкой в момент вызова

Метод можно даже «одолжить» у соседнего объекта — и this послушно переключится на нового хозяина.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Раз this — это «объект перед точкой», то без точки его нет. Сохраните метод в отдельную переменную, вызовите как обычную функцию — и связь с объектом порвётся.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Это частая ловушка при передаче методов в колбэки. Лекарство — привязка через 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, чтобы работать с любым именем.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Добавьте метод greet() { console.log(`Привет, ${this.name}!`); }. Внутри метода this — это сам player, поэтому при смене имени в объекте приветствие обновится само.

Счётчик

Допишите объекту counter два метода: up() увеличивает value на единицу, show() печатает текущее значение. После двух вызовов up() метод show() должен вывести 2.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

up() { this.value++; } и show() { console.log(this.value); }. Оба метода обращаются к одному и тому же объекту через this, поэтому значение накапливается между вызовами.