
Привет, Хабр. Я Саша, разработчик, пишу на JS. Ранее я рассказывал о callback-функциях, деструктуризации, операторах и многом другом. Если вы уже успели познакомиться с основами JavaScript, то наверняка вам знакомы такие понятия, как объекты и функции.
В этой статье мы двинемся дальше и соберем эти знания воедино. Я расскажу вам о методах объектов и загадочном слове this. Разберемся, для чего они нужны, как сделать объекты по-настоящему живыми и как избежать частых ошибок. Ну что, начнем.
Я помню, что для многих из вас JavaScript — это первый язык программирования, поэтому я постараюсь объяснять максимально просто и наглядно, как всегда.
И если вы только начали изучать JS и еще не разобрались, что такое объекты и функции, то настоятельно рекомендую сначала изучить эти темы. Тогда сегодняшний материал будет максимально понятным:
Методы объектов
Прежде чем дать строгое определение, давайте разберем наглядный пример. Представьте, что у нас есть товар в корзине, и мы хотим посчитать его общую стоимость:
const product = {
name: "Кофе",
price: 600,
count: 2,
};
function getTotalPrice(product) {
return product.price * product.count;
}
console.log(getTotalPrice(product));

Что здесь происходит
У нас есть объект product, который хранит данные о товаре. Отдельно от него существует функция getTotalPrice, которая для расчетов должна явно получить этот объект. А сама логика расчета тесно связана с объектом, но формально находится снаружи.
Какие здесь минусы
Функция и объект существуют отдельно. В большом коде не сразу поймешь, что эта функция работает именно с этим объектом.
Неудобство использования. Каждый раз для расчета нужно передавать объект в функцию.
Хрупкость. Если структура объекта изменится (например, свойство count переименуется в quantity), придется исправлять все функции, которые с ним работают.
А теперь предлагаю решить эту же задачу с использованием аналогичной функции, но уже в виде метода. Давайте встроим функцию прямо в объект, сделав ее его частью:
const product = {
name: "Кофе",
price: 600,
count: 2,
getTotalPrice: function () {
return product.price * product.count;
}
};
console.log(product.getTotalPrice(product));

Что же изменилось? Функция getTotalPrice теперь находится внутри объекта product. Она стала его неотъемлемой частью. А для ее вызова мы обращаемся к самому объекту через точку: product.getTotalPrice(). Так мы подходим к главному термину.
Метод — это функция, являющаяся свойством объекта. Если свойство хранит функцию, оно называется методом этого объекта.
Чем методы отличаются от обычных функций
Функция существует сама по себе, ее можно вызвать откуда угодно. А метод привязан к объекту. Он описывает действие, которое может совершить этот объект. Вызов метода всегда связан с объектом, к которому он принадлежит — через точку или квадратные скобки.
Вы наверняка заметили странность в коде метода. Да, функция теперь внутри объекта, но для доступа к данным (product.price) она по-прежнему использует внешнюю переменную product:
getTotalPrice: function () {
return product.price * product.count;
}
Этот подход очень ненадежен. Почему это проблема:
если мы переименуем константу
productвcoffee, метод сразу сломается;если этот объект будет элементом массива, у него не будет внешнего имени
product;при передаче объекта в другую функцию мы теряем его исходное имя.
Это осознанный недостаток текущего примера, и именно он подводит нас к необходимости более правильного решения.
В следующей части мы узнаем, как заставить метод работать с данными своего объекта, не завися от внешних переменных. Для этого в JavaScript существует специальное и очень важное ключевое слово — this.

Бесплатный базовый курс по JS
Рассказываем, как работать с переменными, типами данных, функциями и о многом другом!
Что такое this
Итак, мы столкнулись с проблемой. Наш метод был зашит на внешнюю переменную product, что делало его хрупким и ненадежным. Но прежде чем решить эту проблему, разберемся в понятии this.
this — это специальное ключевое слово в JavaScript, которое ссылается на объект, в контексте которого была вызвана функция. Проще говоря, this — это текущий владелец выполняемого кода. Внутри метода объекта this — это и есть сам этот объект (обычно).
this позволяет методу получить доступ к данным своего объекта, не зная и не используя его внешнее имя. Метод становится переносимым и независимым. Он говорит: «Возьми данные у того объекта, который меня вызвал (у моего this), а не ищи какую-то внешнюю переменную product».
Перепишем наш код с использованием this:
const product = {
name: "Кофе",
price: 600,
count: 2,
getTotalPrice: function () {
return this.price * this.count;
}
};
console.log(product.getTotalPrice());

Что изменилось?
Вместо
product.priceмы пишемthis.price.Вместо
product.countмы пишемthis.count.
Когда мы вызываем метод как product.getTotalPrice(), JavaScript понимает, что функция была вызвана в контексте объекта product. Поэтому внутри этой функции слово this автоматически становится ссылкой на объект product.
Мы выяснили, что this — это удобный способ обратиться к самому объекту внутри метода, не привязываясь к его внешнему имени. Теперь давайте познакомимся с ключевой особенностью использования this.
Главное правило — this определяется в момент вызова. Значение this не фиксировано. Оно определяется не там, где функция объявлена, а тем, как она была вызвана.
В нашем примере this работает предсказуемо, потому что мы вызываем метод через точку — product.getTotalPrice(). В этом случае this внутри метода и есть product. Но если метод присвоить в константу как ссылку, то this внутри него уже не будет содержать ссылку на этот объект:
const product = {
name: "Кофе",
price: 600,
count: 2,
getTotalPrice: function () {
return this.price * this.count;
}
};
const getTotalPrice2 = product.getTotalPrice;
console.log(getTotalPrice2());

Поведение this — это большая и сложная тема в JavaScript, и в этой статье мы касаемся лишь ее основы. По мере изучения языка мы будем возвращаться к ней снова и снова, рассматривая более сложные случаи. А для закрепления предлагаю посмотреть на небольшой пример работы с методами и объектами в массиве.
Практика для закрепления
Вы уже знаете, как создавать методы в объекте. А как обстоят дела с массивом таких объектов? Давайте создадим несколько товаров с помощью функции-конструктора и выведем их в консоль:
// Функция для создания товаров
function createProduct(name, price, count) {
return {
name: name,
price: price,
count: count,
getTotalPrice: function() {
return this.price * this.count;
},
getInfo: function() {
return ${this.name} | ${this.count} шт. | ${this.getTotalPrice()} руб.;
}
};
}
// Создаем массив товаров
const products = [
createProduct("Кофе", 600, 2),
createProduct("Чай", 300, 3),
createProduct("Печенье", 150, 5),
createProduct("Шоколад", 200, 1)
];
// Выводим информацию о каждом товаре в консоль
for (const product of products) {
console.log(product.getInfo());
}

В этот раз у нас уже два метода, и один из методов даже использует соседний. Да, так можно. Кстати, о функциях-конструкторах и операторе new в дальнейшем вы, конечно, узнаете больше, а пока подведем итог.
Итог
Сегодня мы сделали важный шаг в изучении JavaScript. Давайте тезисно подчеркнем то, что узнали:
методы — это функции внутри объектов, которые делают наши данные живыми;
this— это способ метода обратиться к своему объекту без привязки к внешнему имени.
Не переживайте, если тема кажется сложной, уверенность придет с практикой. Экспериментируйте, пишите код! Попробуйте создать свои объекты с методами, чтобы закрепить знания.
А впереди нас ждет много интересного: поведение this в стрелочных функциях и разных режимах браузера, а также способы работы с контекстом.
Поведение ключевого слова
thisв JavaScript существенно зависит от режима выполнения кода. Во избежание ошибок, рекомендую принудительно включать «use strict».Он решает типичную ошибку: когда
thisуказывает на глобальный объект, а не то, что подразумевал разработчик. Чтобы избежать этого, в «строгом» режиме значениеthisв функциях, которые вызываются без контекста, будет равноundefined, а не глобальному объекту.Современные браузеры по умолчанию включают «строгий» режим только при загрузке модулей и в классах.
Жду вас в следующих статьях!