Конструкторы и классы
Free PreviewВ уроке про типы данных мы видели, что объекты позволяют группировать связанные данные. Но что если нужно создавать много похожих объектов одного «вида» — например, сотни карточек товаров или пользователей? Создавать каждый вручную неудобно. Для этого в JavaScript существуют конструкторы и классы.
Конструктор-функция
Исторически для создания объектов одного вида использовались конструктор-функции. По соглашению их называют с заглавной буквы:
function City(name, foundedYear) { this.name = name; this.foundedYear = foundedYear; this.getAge = function() { return new Date().getFullYear() - this.foundedYear; }; } const spb = new City('Санкт-Петербург', 1703); const msk = new City('Москва', 1147); console.log(spb.name); // Санкт-Петербург console.log(msk.getAge()); // примерно 877js
Ключевое слово new при вызове функции делает несколько вещей автоматически: создаёт новый пустой объект, передаёт его как this внутрь функции, и возвращает этот объект в конце.
Классы
В современном JavaScript есть более удобный синтаксис для той же задачи — классы. По сути, это «синтаксический сахар» поверх конструктор-функций: под капотом работает та же механика, просто записывается чище:
class City { constructor(name, foundedYear) { this.name = name; this.foundedYear = foundedYear; } getAge() { return new Date().getFullYear() - this.foundedYear; } describe() { console.log(`${this.name} основан в ${this.foundedYear} году.`); } } const spb = new City('Санкт-Петербург', 1703); spb.describe(); // Санкт-Петербург основан в 1703 году.js
Метод constructor вызывается автоматически при создании объекта через new. Остальные методы описываются внутри тела класса.
Наследование
Классы поддерживают наследование — один класс может расширять другой, получая его свойства и методы:
class Settlement { constructor(name) { this.name = name; } greet() { console.log(`Добро пожаловать в ${this.name}!`); } } class City extends Settlement { constructor(name, foundedYear) { super(name); // вызываем конструктор родителя this.foundedYear = foundedYear; } getAge() { return new Date().getFullYear() - this.foundedYear; } } const spb = new City('Санкт-Петербург', 1703); spb.greet(); // Добро пожаловать в Санкт-Петербург! — метод из родителя spb.getAge(); // метод из Cityjs
extends указывает, от какого класса наследоваться. super() внутри конструктора вызывает конструктор родительского класса — это обязательно, если дочерний класс объявляет constructor.
Статические методы и свойства
Иногда нужны методы, которые относятся к самому классу, а не к конкретному экземпляру. Для этого используется ключевое слово static:
class City { constructor(name) { this.name = name; } static create(name) { return new City(name); } } const spb = City.create('Санкт-Петербург'); // вызов через класс, не через экземпляр console.log(spb.name); // Санкт-Петербургjs
Статические методы вызываются через имя класса, а не через созданный объект.
Важно понимать
Классы в JavaScript — это не то же самое, что классы в Java или C#. Это лишь удобная обёртка над механизмом прототипов, который лежит в основе JavaScript. Если вы захотите углубиться в тему — изучите прототипное наследование и цепочку прототипов. Это поможет понять язык на более глубоком уровне. Хорошее объяснение можно найти на doka.guide.
В следующем уроке подробнее рассмотрим массивы — один из самых используемых инструментов в повседневной разработке.