JS: Введение в ООП
Теория: Конструктор
Приложения на JavaScript во время своей работы создают и удаляют множество объектов. Иногда эти объекты совсем разные, а иногда они относятся к одному понятию, но отличаются данными. Когда речь идет про понятия предметной области (или, как говорят, сущности), то важно иметь абстракцию, которая скроет от нас структуру этого объекта.
Возьмем понятие "компания" и построим абстракцию вокруг него без использования инкапсуляции:
Теперь использование:
Такая абстракция упрощает работу с компаниями (особенно при изменениях структуры), прячет детали реализации и делает код более "человечным". Попробуем сделать то же самое, используя инкапсуляцию:
И использование:
Здесь мы видим несколько удобных моментов по сравнению с вариантом на функциях:
- Нам больше не надо импортировать
getName, он уже содержится внутри компании. - Можно пользоваться автодополнением кода (среда разработки сама подскажет все свойства и методы, существующие в
company).
Но вместе с плюсами пришли и минусы. Посмотрите еще раз внимательно на код конструктора. Каждый его вызов возвращает новый объект и это ожидаемое поведение, но чего мы точно не хотим, так это создания методов на каждый вызов конструктора (а они будут создаваться при каждом создании объекта). Методы, в отличие от обычных данных, не меняются. Нет никакого смысла создавать их на каждый вызов заново, расходуя память и процессорное время.
Перепишем наш пример, избежав постоянного создания методов:
Оператор new
Все описанные выше способы создания объектов имеют право на существование и используются в реальной жизни, но в JavaScript есть встроенная поддержка генерации объектов. Перепишем наш пример с помощью функции-конструктора.
Теперь использование:
Самое интересное в этом примере – оператор new (как и многое в js, он работает не так, как new в других языках). Фактически он создает объект, устанавливает его как контекст во время вызова конструктора (в данном случае Company) и возвращает созданный объект. Именно поэтому сам конструктор ничего не возвращает (хотя может, но это другой разговор), а внутри константы company оказывается нужный нам объект.
Визуально этот способ выглядит не лучше, чем предыдущее ручное создание, но он задействует еще один важный механизм в JavaScript – прототипы (Подробнее о них в следующем уроке).
Все типы данных в JavaScript, которые могут быть представлены объектами (или являются объектами внутри себя, например, функции), имеют встроенные конструкторы. Иногда они заменяют специальный синтаксис создания данных (как в случае с массивами), а иногда это единственный способ создать данные этого типа (как в случае с датами):
Но не все функции могут быть конструкторами. Отсутствие своего контекста делает невозможным использование оператора new вместе со стрелочными функциями:






