Skip to main content

Метод класу VS функція у властивості об'єкта

1. Синтаксис

Метод класу:

javascript
class User { greet() { console.log(`Hi, ${this.name}`); } }

Функція-властивість об'єкта:

javascript
const user = { greet: function() { console.log(`Hi, ${this.name}`); } };

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


2. Де зберігається метод

ПідхідДе зберігається функція
Метод класуУ User.prototype
Функція-властивість об'єктаУ самому об'єкті (у його «тілі»)

Приклад:

javascript
class A { sayHi() {} } const a1 = new A(); const a2 = new A(); console.log(a1.sayHi === a2.sayHi); // true: метод один на всіх // А тепер об'єкт const obj1 = { sayHi: function() {} }; const obj2 = { sayHi: function() {} }; console.log(obj1.sayHi === obj2.sayHi); // false: у кожного своя копія

Методи класу економлять пам'ять, бо один метод зберігається в прототипі й використовується всіма екземплярами.


3. Створення і момент виділення функції

  • У класі метод додається один раз під час визначення класу.
  • В об'єкті функція-властивість створюється щоразу під час створення нового об'єкта.

Тобто якщо ти створюєш 1000 екземплярів класу, всі вони ділять один метод. А якщо створюєш 1000 об'єктів із функцією-властивістю, у пам'яті буде 1000 різних функцій.


4. Відмінність під час успадкування

Методи класу автоматично беруть участь в успадкуванні через prototype.

javascript
class Animal { speak() { console.log("The animal makes a sound"); } } class Dog extends Animal {} const dog = new Dog(); dog.speak(); // The animal makes a sound

А от об'єкт із функцією-властивістю не бере участі в успадкуванні (якщо не використовувати Object.create).


5. Відмінність у синтаксисі super

super (виклик батьківського методу) працює лише в класах, а у звичайних об'єктах, ні (якщо не застосовувати просунуті прийоми з Object.setPrototypeOf).

javascript
class A { greet() { console.log("Hi from A"); } } class B extends A { greet() { super.greet(); // доступний console.log("Hi from B"); } }

В об'єкті:

javascript
const a = { greet() { console.log("Hi from A"); } }; const b = { greet() { // super.greet(); не працює без прототипу console.log("Hi from B"); } };

6. Поведінка this

І в класі, і в об'єкті метод зберігає this, але якщо передати його як колбек, this втрачається (якщо це не стрілкова функція):

javascript
class A { hello() { console.log(this); // A } } const a = new A(); setTimeout(a.hello, 1000); // undefined (контекст втрачено)

Те саме з об'єктом:

javascript
const obj = { hello() { console.log(this); } }; setTimeout(obj.hello, 1000); // undefined

Якщо потрібно зберегти контекст, використовують стрілкові функції як властивості:

javascript
class A { hello = () => { console.log(this); // завжди правильний this }; }

7. Різниця у визначенні (опис на рівні мови)

ВідмінністьМетод класуФункція-властивість об'єкта
Де зберігаєтьсяClass.prototypeУ самому об'єкті
Спільна для екземплярівТакНі
Створюється під часВизначення класуСтворення об'єкта
Бере участь в успадкуванніТакНі
Доступ до superТакНі
Втрата this у колбекуТак (якщо не стрілка)Так (якщо не стрілка)
Продуктивність і пам'ятьЕфективнішеМенш ефективно

Приклад для візуалізації

javascript
class User { greet() { console.log("I am a class method"); } } const obj = { greet() { console.log("I am an object property function"); } }; console.log(Object.getOwnPropertyNames(User.prototype)); // ["constructor", "greet"] console.log(Object.keys(obj)); // ["greet"]

Підсумок: Методи класу, це функції в прототипі, спільні для всіх екземплярів (економлять пам'ять, беруть участь в успадкуванні, підтримують super). Функції-властивості об'єкта, це звичайні властивості, що належать конкретному об'єкту, створюються заново щоразу і не беруть участі в успадкуванні.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.