Чим клас відрізняється від функції-конструктора?
1. Синтаксис і читабельність
Функція-конструктор:
function User(name) {
this.name = name;
}
User.prototype.greet = function () {
console.log(`Hi, ${this.name}`);
};
const user = new User("Alice");
user.greet();Клас:
class User {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hi, ${this.name}`);
}
}
const user = new User("Alice");
user.greet();Клас виглядає чистіше й декларативніше, особливо при успадкуванні.
Функція-конструктор вимагає вручну прописувати prototype, Object.create() тощо.
2. Поведінка під час виклику без new
-
Функцію-конструктор можна випадково викликати без
new, і це призведе до помилок (наприклад,thisстанеundefinedу strict-режимі або прив'яжеться доwindow):javascriptfunction User(name) { this.name = name; } const u = User("Alice"); // Помилка або створить глобальну властивість window.name -
Клас не можна викликати без
new, це викличе виняток:javascriptclass User { constructor(name) { this.name = name; } } const u = User("Alice"); // TypeError: Class constructor User cannot be invoked without 'new'
Це робить класи безпечнішими.
3. Класи завжди мають строгий режим (strict mode)
Все тіло класу автоматично працює в strict mode,
навіть якщо 'use strict' не написано.
А от функція-конструктор, ні, якщо явно не вказати 'use strict'.
4. Методи класу не перелічувані
Тобто методи, визначені всередині class {}, не з'являються під час перебору for...in,
а методи в prototype функції-конструктора, перелічувані:
class A {
m() {}
}
console.log(Object.keys(A.prototype)); // []
function B() {}
B.prototype.m = function() {};
console.log(Object.keys(B.prototype)); // ["m"]Це робить класи більш "чистими" для ітерації та серіалізації.
5. У класах не можна оголошувати методи як звичайні функції
Якщо в тілі класу спробувати написати:
class A {
m = function() {}; // SyntaxError у старих версіях
}потрібно використовувати синтаксис полів класу або стрілкові функції, які з'явилися пізніше (ES2022+).
6. Класи не мають hoisting (підняття)
-
Функції-конструктори можна викликати до їх оголошення (через hoisting):
javascriptconst a = new User(); function User() {} -
Класи не можна:
javascriptconst a = new User(); // ReferenceError class User {}
Це запобігає неочікуваним помилкам виконання.
7. Успадкування простіше
З функціями-конструкторами потрібно писати багато зайвого:
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a sound`);
};
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;А з класами:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} barks`);
}
}Коротко і зрозуміло.
Підсумкова таблиця
| Відмінність | Клас | Функція-конструктор |
|---|---|---|
Виклик без new | Помилка | Працює, але може призвести до багів |
| Strict mode | Завжди увімкнено | Не за умовчанням |
| Hoisting | Немає | Є |
| Методи перелічувані | Ні | Так |
| Синтаксис успадкування | Простий (extends) | Складний (Object.create, call) |
| Приватні поля | Є (#field) | Немає |
| Читабельність | Висока | Низька |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.