Конструкторы
1. Конструкторы
Обычный синтаксис литерала объекта {}
позволяет создать один объект. Но зачастую нужно создать много однотипных объектов динамически во время выполнения программы. Для этого используют функции-конструкторы, вызывая их при помощи специального оператора new
.
Конструктор — это обычная функция, к которой применили оператор new
. Это приводит к созданию нового объекта и вызову функции в контексте этого объекта.
Любая функция, кроме стрелочной, может быть использована как конструктор, то есть вызвана при помощи оператора new
. При вызове стрелки через new
будет ошибка.
Чтобы отличить конструктор от обычной функции, конструкторы принято называть с большой буквы, а в самом названии отражать тип создаваемого объекта. Мы уже работали с конструкторами встроенными в язык: Object
, Array
, Number
, String
и другие.
Процесс создания объекта через конструктор происходит следующим образом:
Создаётся новый пустой объект.
Функция-конструктор вызывается в контексте этого объекта.
Ключевое слово
this
внутри конструктора получает ссылку на этот объект.Конструктор выполняется и, как правило, модифицирует
this
(созданный объект), добавляя свойства и методы.Возвращается
this
.
const Hotel = function (name, stars, capacity) {
this.name = name;
this.stars = stars;
this.capacity = capacity;
};
// В результате вызова
const hotel = new Hotel('Resort Hotel', 5, 100);
// Получаем такой объект
console.log(hotel);
// Hotel {name: "Resort Hotel", stars: 5, capacity: 100}
Copy
Если визуализировать происходящее, то при вызове new Hotel
происходит следующее (первая и последняя строка — это то, что делает интерпретатор).
const Hotel = function (name, stars, capacity) {
// this = {};
// в this пишем свойства и методы
this.name = name;
this.stars = stars;
this.capacity = capacity;
// return this;
};
Copy
Теперь многократными вызовами new Hotel
с разными аргументами мы можем создать любое количество объектов. Использование конструкторов удобно при создании множества объектов с одним набором свойств, имеющих разные значения. Поэтому такую функцию и называют конструктором — она предназначена для конструирования объектов по заранее подготовленному шаблону.
const Hotel = function (name, stars, capacity) {
this.name = name;
this.stars = stars;
this.capacity = capacity;
};
const hotel = new Hotel('Resort Hotel', 5, 100);
console.log(hotel);
// Hotel {name: "Resort Hotel", stars: 5, capacity: 100}
const motel = new Hotel('Sunlight Motel', 4, 300);
console.log(motel);
// Hotel {name: "Sunlight Motel", stars: 4, capacity: 300}
Copy
2. Внутренние методы [[Call]] и [[Construct]]
Функции вызываются используя два разных внутренних метода: [[Call]]
и [[Construct]]
.
Когда функция вызывается без
new
, выполняется метод[[Call]]
, который исполняет тело функции так, как оно описано в коде.Когда функция вызывается с
new
, выполняется метод[[Construct]]
, который отвечает за создание нового объекта и исполнения тела функции сthis
, ссылающимся на этот объект.
Не все функции имеют внутренний метод [[Construct]]
и поэтому не все функции могут быть вызваны через new
. Стрелочные функции не имеют метода [[Construct]]
и поэтому не могут быть использованы в качестве конструкторов.
3. Добавление методов
Использование функций для создания объекта дает большую гибкость. Можно передавать конструктору параметры, определяющие как его создавать и он будет создавать объекты заданным образом.
Добавим метод в создаваемый объект. Например, пусть Hotel
имеет методы для приветствия гостя и добавления и удаления количества гостей в поле guestCount
. Проверки на вместительность пропустим.
const Hotel = function (name, stars, capacity) {
this.name = name;
this.stars = stars;
this.capacity = capacity;
this.guestCount = 0;
this.greet = function (guestName) {
console.log(`Hello ${guestName}, wellcome to ${this.name}`);
};
this.addGuests = function (amount) {
this.guestCount += amount;
};
this.removeGuests = function (amount) {
this.guestCount -= amount;
};
};
const hotel = new Hotel('Sunrise Hotel', 5, 100);
console.log(hotel);
// Hotel {name: "Sunrise Hotel", greet: ƒ, addGuests: f, removeGuests: f}
hotel.greet('Mango'); // Hello Mango, wellcome to Sunrise Hotel
hotel.addGuests(50);
hotel.removeGuests(50);
Copy
4. Управляем магазином
Время практики. Представьте, что у нас есть магазин и два менеджера, по продаже товаров. Необходимо написать логику для организации их работы. Для каждого менеджера создаётся отдельный объект.
const mango = {
name: 'Mango',
sales: 5,
sell(product) {
this.sales += 1;
return `Manager ${this.name} sold ${product}.`;
},
};
console.log(mango.sales); // 5
console.log(mango.sell('TV')); // Manager Mango sold TV
console.log(mango.sell('Microwave')); // Manager Mango sold Microwave
console.log(mango.sales); // 7
const poly = {
name: 'Poly',
sales: 10,
sell(product) {
this.sales += 1;
return `Manager ${this.name} sold ${product}.`;
},
};
console.log(poly.sales); // 10
console.log(poly.sell('TV')); // Manager Poly sold TV
console.log(poly.sell('Microwave')); // Manager Poly sold Microwave
console.log(poly.sales); // 12
Copy
Это было просто и всё работает хорошо, но мы буквально захардкодили менеджеров заранее. Представьте что будет, когда наш магазин вырастет и пополнится парой сотен менеджеров, для каждого из которых будет необходимо создать объект динамически во время выполнения программы. Очевидно, что создавать объекты подобным способом — не самая лучшая затея. К счастью, мы знаем о конструкторах.
const Manager = function (name = 'manager', sales = 0) {
this.name = name;
this.sales = sales;
this.sell = function (product) {
this.sales += 1;
return `Manager ${this.name} sold ${product}.`;
};
};
const mango = new Manager('Mango', 5);
console.log(mango.sales); // 5
console.log(mango.sell('TV')); // Manager Mango sold TV
console.log(mango.sell('Microwave')); // Manager Mango sold Microwave
console.log(mango.sales); // 7
const poly = new Manager('Poly', 10);
console.log(poly.sales); // 10
console.log(poly.sell('TV')); // Manager Poly sold TV
console.log(poly.sell('Microwave')); // Manager Poly sold Microwave
console.log(poly.sales); // 12
Copy
Теперь, когда мы узнаем как работать с HTML-документом, нам не страшно любое количество менеджеров. Собрав поля из форм регистрации, можно динамически создавать объекты по введенной информации.
Last updated