Что такое статические методы в javascript

Статические и фабричные методы

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/static-properties-methods.

Методы и свойства, которые не привязаны к конкретному экземпляру объекта, называют «статическими». Их записывают прямо в саму функцию-конструктор.

Статические свойства

В коде ниже используются статические свойства Article.count и Article.DEFAULT_FORMAT :

Они хранят данные, специфичные не для одного объекта, а для всех статей целиком.

Статические методы

С примерами статических методов мы уже знакомы: это встроенные методы String.fromCharCode, Date.parse.

Создадим для Article статический метод Article.showCount() :

Здесь Article.count – статическое свойство, а Article.showCount – статический метод.

Пример: сравнение объектов

Ещё один хороший способ применения – сравнение объектов.

Например, у нас есть объект Journal для журналов. Журналы можно сравнивать – по толщине, по весу, по другим параметрам.

Объявим «стандартную» функцию сравнения, которая будет сравнивать по дате издания. Эта функция сравнения, естественно, не привязана к конкретному журналу, но относится к журналам вообще.

Поэтому зададим её как статический метод Journal.compare :

В примере ниже эта функция используется для поиска самого раннего журнала из массива:

Статический метод также можно использовать для функций, которые вообще не требуют наличия объекта.

Например, метод formatDate(date) можно сделать статическим. Он будет форматировать дату «как это принято в журналах», при этом его можно использовать в любом месте кода, не обязательно создавать журнал.

Фабричные методы

Рассмотрим ситуацию, когда объект нужно создавать различными способами. Например, это реализовано во встроенном объекте Date. Он по-разному обрабатывает аргументы разных типов:

«Фабричный статический метод» – удобная альтернатива такому конструктору. Так называется статический метод, который служит для создания новых объектов (поэтому и называется «фабричным»).

Пример встроенного фабричного метода – String.fromCharCode(code). Этот метод создаёт строку из кода символа:

Но строки – слишком простой пример, посмотрим что-нибудь посложнее.

Можно, конечно, создать полиморфную функцию-конструктор User :

Преимущества использования фабричных методов:

Поэтому полиморфные конструкторы лучше использовать там, где нужен именно полиморфизм, т.е. когда непонятно, какого типа аргумент передадут, и хочется в одном конструкторе охватить все варианты.

А в остальных случаях отличная альтернатива – фабричные методы.

Итого

Статические свойства и методы объекта удобно применять в следующих случаях:

Задачи

Счётчик объектов

Добавить в конструктор Article :

Используйте для этого статические свойства.

Источник

JavaScript: полное руководство по классам

Доброго времени суток, друзья!

В JavaScript используется модель прототипного наследования: каждый объект наследует поля (свойства) и методы объекта-прототипа.

Классов, используемых в Java или Swift в качестве шаблонов или схем для создания объектов, в JavaScript не существует. В прототипном наследовании есть только объекты.

Прототипное наследование может имитировать классическую модель наследования от классов. Для этого в ES6 было представлено ключевое слово class: синтаксический сахар для прототипного наследования.

В данной статье мы научимся работать с классами: определять классы, их частные (приватные) и открытые (публичные) поля и методы, а также создавать экземпляры.

1. Определение: ключевое слово class

Для определения класса используется ключевое слово class:

Такой синтаксис называется объявлением класса.

Класс может не иметь названия. С помощью выражения класса можно присвоить класс переменной:

Классы можно экспортировать в виде модулей. Вот пример экспорта по умолчанию:

А вот пример именованного экспорта:

Классы используются для создания экземпляров. Экземпляр — это объект, содержащий данные и логику класса.

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

Экземпляры создаются с помощью оператора new: instance = new Class().

Вот как создать экземпляр класса User:

2. Инициализация: constructor()

В следующем примере конструктор устанавливает начальное значение поля name:

Конструктор принимает один параметр — name, который используется для установки начального значения поля this.name.

this в конструкторе указывает на создаваемый экземпляр.

Аргумент, используемый для создания экземпляра класса, становится параметром его конструктора:

Параметр name внутри конструктора имеет значение ‘Печорин’.

Если не определить собственный конструктор, будет создан стандартный конструктор, представляющий собой пустую функцию, не влияющую на экземпляр.

3. Поля

Поля класса — это переменные, содержащие определенную информацию. Поля могут быть разделены на две группы:

3.1. Открытые поля экземпляров класса

Выражение this.name = name создает поле экземпляра name и присваивает ему начальное значение.

Доступ к этому полю можно получить с помощью аксессора свойства:

В данном случае name — открытое поле, поскольку оно доступно за пределами класса User.

При неявном создании полей внутри конструктора, сложно получить список всех полей. Для этого поля нужно извлекать из конструктора.

Лучшим способом является явное определение полей класса. Неважно, что делает конструктор, экземпляр всегда имеет одинаковый набор полей.

Предложение по созданию полей класса позволяет определять поля внутри класса. Кроме того, здесь же можно присваивать полям начальные значения:

Изменим код класса User, определив в нем открытое поле name:

Такие открытые поля являются очень наглядными, быстрый взгляд на класс позволяет понять структуру его данных.

Более того, поле класса может быть инициализировано в момент определения:

На доступ к открытым полям и их изменение нет ограничений. Читать и присваивать значения таким полям можно в конструкторе, методах и за пределами класса.

3.2. Частные поля экземпляров класса

Инкапсуляция позволяет скрывать внутренние детали реализации класса. Тот, кто использует инкапсулированный класс, опирается на публичный интерфейс, не вдаваясь в подробности реализации класса.

Такие классы проще обновлять при изменении деталей реализации.

Хорошим способом скрыть детали является использование частных полей. Такие поля могут быть прочитаны и изменены только внутри класса, которому они принадлежат. За пределами класса частные поля недоступны.

Для того, чтобы сделать поле частным, перед его названием следует поставить символ #, например, #myPrivateField. При обращении к такому полю всегда должен использоваться указанный префикс.

Сделаем поле name частным:

#name — частное поле. Доступ к нему можно получить только внутри класса User. Это позволяет сделать метод getName().

Однако, при попытке получить доступ к #name за пределами класса User будет выброшена синтаксическая ошибка: SyntaxError: Private field ‘#name’ must be declared in an enclosing class.

3.3. Открытые статические поля

В классе можно определить поля, принадлежащие самому классу: статические поля. Такие поля используются для создания констант, хранящих нужную классу информацию.

Для создания статических полей используется ключевое слово static перед названием поля: static myStaticField.

Добавим новое поле type для определения типа пользователя: администратора или обычного. Статические поля TYPE_ADMIN и TYPE_REGULAR — константы для каждого типа пользователей:

Для доступа к статическим полям следует использовать название класса и название свойства: User.TYPE_ADMIN и User.TYPE_REGULAR.

3.4. Частные статические поля

Иногда статические поля также являются частью внутренней реализации класса. Для инкапсуляции таких полей можно сделать их частными.

Для этого следует перед названием поля поставить префикс #: static #myPrivateStaticFiled.

Предположим, что мы хотим ограничить количество экземпляров класса User. Для сокрытия информации о количестве экземпляров можно создать частные статические поля:

Статическое поле User.#MAX_INSTANCES определяет допустимое количество экземпляров, а User.#instances — количество созданных экземпляров.

Эти частные статические поля доступны только внутри класса User. Ничто из внешнего мира не может повлиять на ограничения: в этом заключается одно из преимуществ инкапсуляции.

Прим. пер.: если ограничить количество экземпляров одним, получится интересная реализация шаблона проектирования «Одиночка» (Singleton).

4. Методы

Поля содержат данные. Возможность изменять данные обеспечивается специальными функциями, являющимися частью класса: методами.

JavaScript поддерживает как методы экземпляров класса, так и статические методы.

4.1. Методы экземпляров класса

Методы экземпляра класса могут изменять его данные. Методы экземпляра могут вызывать другие методы экземпляра, а также статические методы.

Например, определим метод getName(), возвращающий имя пользователя:

В методе класса, также как и в конструкторе, this указывает на создаваемый экземпляр. Используйте this для получения данных экземпляра: this.field, или для вызова методов: this.method().

Добавим новый метод nameContains(str), принимающий один аргумент и вызывающий другой метод:

nameContains(str) — метод класса User, принимающий один аргумент. Он вызывает другой метод экземпляра getName() для получения имени пользователя.

Метод также может быть частным. Для того, чтобы сделать метод частным следует использовать префикс #.

Сделаем метод getName() частным:

#getName() — частный метод. Внутри метода nameContains(str) мы вызываем его так: this.#getName().

Будучи частным, метод #getName() не может быть вызван за пределами класса User.

4.2. Геттеры и сеттеры

Геттеры и сеттеры — это аксессоры или вычисляемые свойства. Это методы, имитирующие поля, но позволяющие читать и записывать данные.

Геттеры используются для получения данных, сеттеры — для их изменения.

Для установки запрета на присвоение полю name пустой строки, обернем частное поле #nameValue в геттер и сеттер:

4.3. Статические методы

Статические методы — это функции, принадлежащие самому классу. Они определяют логику класса, а не его экземпляров.

Для создания статического метода используется ключевое слово static перед названием метода: static myStaticMethod().

При работе со статическими методами, следует помнить о двух простых правилах:

isNameTaken() — статический метод, использующий частное статическое поле User.#takenNames для определения использованных имен.

Статические методы также могут быть частными: static #myPrivateStaticMethod(). Такие методы могут вызываться только внутри класса.

5. Наследование: extends

Классы в JavaScript поддерживают наследование с помощью ключевого слова extends.

В выражении class Child extends Parent < >класс Child наследует от класса Parent конструктор, поля и методы.

Создадим дочерний класс ContentWriter, расширяющий родительский класс User:

ContentWriter наследует от User конструктор, метод getName() и поле name. В самом ContentWriter определяется новое поле posts.

Обратите внимание, что частные поля и методы родительского класса не наследуются дочерними классами.

5.1. Родительский конструктор: super() в constructor()

Для того, чтобы вызвать конструктор родительского класса в дочернем классе, следует использовать специальную функцию super(), доступную в конструкторе дочернего класса.

Пусть конструктор ContentWriter вызывает родительский конструктор и инициализирует поле posts:

super(name) в дочернем классе ContentWriter вызывает конструктор родительского класса User.

Обратите внимание, что в дочернем конструкторе перед использованием ключевого слова this вызывается super(). Вызов super() «привязывает» родительский конструктор к экземпляру.

5.2. Родительский экземпляр: super в методах

Для того, чтобы получить доступ к родительскому методу внутри дочернего класса, следует использовать специальное сокращение super:

getName() дочернего класса ContentWriter вызывает метод getName() родительского класса User.

Это называется переопределением метода.

Обратите внимание, что super можно использовать и для статических методов родительского класса.

6. Проверка типа объекта: instanceof

Выражение object instanceof Class определяет, является ли объект экземпляром указанного класса.

Оператор instanceof полиморфичен: он исследует всю цепочку классов.

Что если нам нужно определить конкретный класс экземпляра? Для этого можно использовать свойство constructor:

7. Классы и прототипы

Надо сказать, что синтаксис классов — это хорошая абстракция над прототипным наследованием. Для использования классов не нужно обращаться к прототипам.

Однако, классы являются лишь надстройкой над прототипным наследованием. Любой класс — это функция, создающая экземпляр при вызове конструктора.

Следущие два примера идентичны.

Поэтому для понимания классов требуется хорошее знание прототипного наследования.

8. Доступность возможностей классов

Возможности классов, представленные в данной статье, распределены между спецификацией ES6 и предложениями, находящимися на третьей стадии рассмотрения:

Прим. пер.: по данным Can I use поддержка частных полей классов на сегодняшний день составляет 68%.

9. Заключение

Классы в JavaScript используются для инициализации экземпляров с помощью конструктора, определения их полей и методов. С помощью ключевого слова static можно определять поля и методы самого класса.

Наследование реализуется с помощью ключевого слова extends. Ключевое слово super позволяет получить доступ к родительскому классу из дочернего.

Для того, чтобы воспользоваться преимуществами инкапсуляции, т.е. скрыть внутренние детали реализации, сделайте поля и методы частными. Названия таких полей и методов должны начинаться с символа #.

В современном JavaScript классы используются повсеместно.

Надеюсь, статья была вам полезной. Благодарю за внимание.

Источник

Статические методы и свойства классов

На этом занятии мы с вами поговорим о статических методах и свойствах. Что это такое? Давайте предположим, что имеется класс для описания пользователя. Он будет очень простым: хранить имя, возраст и иметь метод, возвращающий имя человека:

Далее, можно создавать объекты этого класса, следующим образом:

Теперь, приходит заказчик и говорит, что надо бы добавить функционал для сравнения пользователей, например, по возрасту. И мы начинаем думать: как это лучше сделать? Из того, что нам известно на этот момент, было бы логично добавить метод для такого сравнения, например, так:

И, затем, использовать его:

Отлично, все работает. Мы потираем руки и радуемся легкости исполнения задания. Но, тут приходит опытный программист, смотрит на весь этот код, и начинает изрыгать нелитературные выражения в наш адрес! Что ему не понравилось? Дело вот в чем. Правильнее было бы реализовать функционал для сравнения пользователей на более обобщенном уровне, не привязывая его к объектам каждого пользователя.

Чтобы это поправить, как раз и можно воспользоваться статическими методами. Если записать метод compareOld как статический (перед его именем ставится ключевое слово static):

то он будет принадлежать только классу, но не объектам:

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

Соответственно, из объектов его вызвать уже нельзя и вот такая строчка приведет к ошибке:

Вызвать его можно только непосредственно из класса Users:

Это и означает, что статические методы принадлежат только классам, но не объектам и доступ к таким методам возможен только из класса. В результате, мы получаем некую общую реализацию для сравнения возрастов двух произвольных пользователей. И в контексте нашей задачи, такое решение будет лучшим.

Фактически, слово static «указывает» создавать метод по синтаксису:

Тогда как обычные методы объявляются как свойства объекта prototype:

Наследование статических методов

Но как будут вести себя статические методы при наследовании классов? Предположим, что мы хотим добавить еще одного специализированного пользователя Admin:

Мы расширяем базовый класс Users и добавляем еще два свойства: login и psw. Будет ли статический метод compareOld доступен в дочернем классе Admin? Да, будет и, далее, мы можем создать такого пользователя:

и сравнить их, вызывая статический метод через класс Admin:

То есть, метод compareOld можно вызывать и через класс Users и через класс Admin. Разницы никакой не будет. Это происходит по той причине, что свойство __proto__ класса Admin ссылается на класс Users:

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

Если же добавить еще один статический метод, но уже в класс Admin:

то картина будет такой:

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

В методе createAdmin мы создаем нового пользователя Admin с использованием только двух параметров: name, old. Остальные два задаются по умолчанию как: «admin», «root». Причем, ключевое слово this здесь будет ссылаться на класс, указанный перед точкой, при вызове данного метода. Например:

Здесь this ссылается на Admin, поэтому будет создан новый объект класса Admin. А вот если мы в методе compareOld добавим вывод:

и вызовем его двумя способами:

то в первом случае this будет ссылаться на Users, а во втором – на Admin.

Статические свойства

Недавно в JavaScript была добавлена возможность объявления статических свойств внутри класса, например, так:

Это свойство будет принадлежать только классу Users и не копироваться в его объекты. Например, так можно сделать подсчет числа созданных пользователей в программе. Добавим в конструктор строчку:

И, затем, выведем это свойство в консоль:

Увидим число созданных пользователей.

Видео по теме

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

JavaScript ООП #1: Прототипное наследование, свойство __proto__

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

JavaScript ООП #2: Свойство prototype

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

JavaScript ООП #3: Базовые свойства Object, методы create, getPrototypeOf и setPrototypeOf

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

JavaScript ООП #5: Наследование классов, переопределение методов, функция super

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

JavaScript ООП #6: Статические методы и свойства классов

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

JavaScript ООП #7: Приватные методы и свойства, оператор instanceof

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

JavaScript ООП #8: Примеси (Mixins). Что это, где и для чего используются

Что такое статические методы в javascript. Смотреть фото Что такое статические методы в javascript. Смотреть картинку Что такое статические методы в javascript. Картинка про Что такое статические методы в javascript. Фото Что такое статические методы в javascript

JavaScript ООП #9: Блоки try/catch/finally, оператор throw, проброс исключений

© 2021 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта

Источник

Полное руководство по классам JavaScript

JavaScript использует прототипное наследование: каждый объект наследует свойства и методы от своего объекта-прототипа. В нем не используется традиционный классовый подход для объектов, такой как в языках Java или Swift. Прототипное наследование имеет дело только с объектами.

Но через прототипное наследования можно эмулировать классическое наследование классов. Чтобы привести традиционные классы в JavaScript, в стандарте ES2015 было введено классовый синтаксис, то есть появилось ключевое слово class: которое является синтаксическим сахаром над прототипным наследованием.

Этот пост знакомит вас с классами в JavaScript: как определить класс, инициализировать экземпляр, определить поля и методы, рассматриваются такие понятия как приватные поля, публичные поля, статические поля и методы.

Содержание

1. Определение: ключевое слово class

Специальное ключевое слово class определяет класс в JavaScript:

Приведенный выше код определяет класс User. Фигурные скобки <> определяют тело класса. Обратите внимание, что такой синтаксис называется объявлением класса.

Вы не обязаны указывать название класса. Используя выражение класса, вы можете назначить класс переменной:

Вы можете легко экспортировать класс как часть модуля ES2015.

Вот синтаксис для экспорта по умолчанию:

Класс становится полезным, когда вы создаете экземпляр класса. Экземпляр — это объект, содержащий данные и поведение, описанные классом.

Оператор new создает экземпляр класса в JavaScript таким образом: instance = new Class().

Например, вы можете создать экземпляр класса User с помощью оператора new:

new User() создает экземпляр класса User.

2. Инициализация: constructor()

constructor(param1, param2, …) это специальный метод в теле класса, который инициализирует экземпляр. Это место, где вы можете установить начальные значения для полей или выполнить любые настройки объектов.

В следующем примере конструктор устанавливает начальное значение поля name:

constructor класса User использует один параметр name, который используется для установки начального значения поля this.name.

Внутри конструктора значение this равно вновь созданному экземпляру.

Аргументы, используемые для создания экземпляра класса, становятся параметрами конструктора:

Параметр name внутри конструктора имеет значение ‘Jon Snow’.

Если вы не определяете конструктор для класса, создается конструктор по умолчанию. Конструктор по умолчанию является пустой функцией, которая не изменяет экземпляр.

В то же время класс JavaScript может иметь до одного конструктора.

3. Поля

Поля класса являются переменными, которые содержат информацию. Поля могут быть привязаны к 2 объектам:

Поля также имеют 2 уровня доступности:

3.1 Публичные поля экземпляра

Давайте снова посмотрим на предыдущий фрагмент кода:

Выражение this.name = name создает поля name экземпляра и присваивает ему начальное значение.

Позже вы можете получить доступ к полю name с помощью метода доступа к свойству:

name является публичным полем, поэтому вы можете получить к нему доступ вне тела класса User.

Когда поля создаются неявно внутри конструктора, как в предыдущем сценарии, их может быть сложно понять и интерпритировать в виде списка полей. Вам придется расшифровать их из кода конструктора.

Лучшим подходом является явное объявление полей класса. В этом случае независимо от того, что делает конструктор, экземпляр всегда будет иметь один и тот же набор полей.

Предложение (proposal) TC39 о полях класса позволяет определять поля внутри тела класса. Кроме того, вы можете сразу указать начальное значение:

Давайте изменим класс User и объявим публичное поле name:

name внутри тела класса объявляется как публичное поле.

После такого объявления достаточно быстрого просмотра полей, чтобы понять структуру данных класса.

Более того, поле класса может быть инициализировано сразу при объявлении.

name = ‘Unknown’ внутри тела класса объявляет поля name и инициализирует его значением ‘Unknown’.

3.2 Приватные поля экземпляра

Инкапсуляция — это важная концепция, которая позволяет скрывать внутренние детали класса. Инкапсулированный класс, зависит только от открытого интерфейса, который предоставляет класс, и имеет полностью независимую внутреннюю реализацию класса.

Классы, организованные с учетом инкапсуляции, легче обновлять при изменении деталей реализации.

Хороший способ скрыть внутренние данные объекта — использовать приватные поля. Эти поля могут быть прочитаны и изменены только в пределах класса, к которому они принадлежат. Внешний мир класса не может напрямую изменять приватные поля.

Приватные поля доступны только внутри тела класса.

Для того что бы сделать поле приватным нужно использовать префикс # перед именем поля, например, #myField. Префикс # должен использоваться каждый раз, когда вы работаете с полем: объявление поле, получения или изменение значения.

Давайте удостоверимся, что поле #name будет приватным:

Теперь #name это приватное поле. Вы можете получить доступ и изменить #name только в теле класса User. Метод getName() (подробнее о методах в следующем разделе) может получить доступ к закрытому полю #name.

Но если вы пытаетесь получить доступ к закрытому полю #name вне тела класса User, возникает синтаксическая ошибка: SyntaxError: Private field ‘#name’ must be declared in an enclosing class.

3.3 Публичные статические поля

Вы также можете определить поля для класса в этом случае они будут называться статические поля. Они полезны для определения констант класса или хранения информации, специфичной для этого класса.

Чтобы создать статические поля в классе JavaScript, используйте специальное ключевое слово static, за которым следует имя поля, например: static myStaticField.

Давайте добавим новый тип поля, который указывает тип пользователя: admin или regular. Статические поля TYPE_ADMIN и TYPE_REGULAR являются удобными константами для различения пользовательских типов:

static TYPE_ADMIN и static TYPE_REGULAR определяют статические переменные внутри класса User. Чтобы получить доступ к статическим полям, вы должны использовать класс, за которым следует имя поля: User.TYPE_ADMIN и User.TYPE_REGULAR.

3.4 Приватные статические поля

Иногда даже статические поля — это детали реализации, которые вы хотели бы скрыть. В связи с этим вы можете сделать статические поля приватными.

Чтобы сделать статическое поле приватным, добавьте к имени поля специальный символ #, например: static #myPrivateStaticField.

Допустим, вы хотите ограничить количество экземпляров класса User. Чтобы скрыть подробности об ограничениях экземпляров, вы можете создать приватное статические поле:

Статическое поле User.#MAX_INSTANCES устанавливает максимальное количество разрешенных экземпляров, в то время как статическое поле User.#instances подсчитывает фактическое количество экземпляров.

Эти частные статические поля доступны только внутри класса User. Ничто из внешнего мира не может помешать механизму ограничений: это преимущество инкапсуляции.

4. Методы

Поля содержат данные. Но возможность изменять данные выполняют специальные функции, которые являются частью класса: методы.

Классы JavaScript поддерживают как экземпляры, так и статические методы.

4.1 Методы экземпляра

Методы экземпляра могут обращаться к данным экземпляра и изменять их. Методы экземпляра могут вызывать другие методы экземпляра, а также любой статический метод.

Например, давайте определим метод getName(), который возвращает имя в классе User:

getName() — это метод внутри класса User. А user.getName() — это вызов метода: он выполняет метод и возвращает вычисленное значение, если оно есть.

В методе класса, как и в конструкторе, значение this равно экземпляру класса. Используйте this для доступа к данным экземпляра, например: this.field или даже для вызова других методов, например: this.method().

Давайте добавим новый метод nameContains(str), который имеет один параметр и вызывает другой метод:

nameContains(str) — это метод класса User, который принимает один параметр str. Более того, он выполняет другой метод экземпляра this.getName(), чтобы получить имя пользователя.

Метод также может быть закрытым. Чтобы сделать метод приватным, добавьте к его имени префикс #.

Давайте сделаем метод getName() приватным:

#getName() является приватным методом. Внутри метода nameContains(str) вызывается приватный метод this.#getName().

Будучи приватным, #getName() не может быть вызван вне тела класса User.

4.2 Getters и setters

getter и setter имитируют обычное поле, но с большим контролем над тем, как поле доступно.

getter выполняется при попытке получить значение поля, а setter при попытке установить значение.

Чтобы убедиться, что свойство name пользователя не может быть пустым, давайте обернем приватное поле #nameValue в методы getter и setter:

get name () getter выполняется при доступе к значению поля user.name.

В то время как set name(name) выполняется при обновлении поля user.name = ‘Jon White’. setter выдаст ошибку, если новое значение будет пустой строкой.

4.3 Статические методы

Статические методы — это функции, прикрепленные непосредственно к классу. Они содержат логику, связанную с классом, а не с экземпляром класса.

При работе со статическими методами нужно помнить 2 простых правила:

Например, давайте создадим статический метод, который определяет, был ли уже выбран пользователь с определенным именем.

isNameTaken() — это статический метод, который использует статическое приватное поле User.#takeNames для проверки принятого значения name.

5. Наследование: extends

Классы в JavaScript поддерживают одиночное наследование с использованием ключевого слова extends.

Например, давайте создадим новый дочерний класс ContentWriter, который расширяет родительский класс User.

ContentWriter наследует от пользователя конструктор, метод getName() и поле name. Также, класс ContentWriter объявляет новое поле posts.

Обратите внимание, что приватные члены родительского класса не наследуются дочерним классом.

5.1 Родительский конструктор: super() в constructor()

Если вы хотите вызвать родительский конструктор в дочернем классе, вам нужно использовать специальную функцию super(), доступную в дочернем конструкторе.

Например, давайте сделаем так, чтобы конструктор ContentWriter вызывал родительский конструктор User, а также инициализировал поле posts:

super(name) внутри дочернего класса ContentWriter выполняет конструктор родительского класса User.

Обратите внимание, что внутри дочернего конструктора вы должны выполнить super() перед использованием ключевого слова this. Вызов super() гарантирует, что родительский конструктор инициализирует экземпляр.

5.2 Экземпляр родителя: super в методах

Если вы хотите получить доступ к родительскому методу внутри дочернего метода, вы можете использовать ключевое слово super.

getName() дочернего класса ContentWriter обращается к методу super.getName() напрямую из родительского класса User.

Эта функция называется переопределением (overriding) метода.

Обратите внимание, что вы также можете использовать super со статическими методами для доступа к статическим методам родителя.

6. Проверка типа объекта: instanceof

object instanceof Class — оператор, который определяет, является ли object экземпляром Class.

Давайте посмотрим оператора instanceof в действии:

user является экземпляром класса User, поэтому user instanceof User оценивается как true.

Пустой объект <> не является экземпляром User, соответственно obj instanceof User равен false.

instanceof является полиморфным: оператор обнаруживает дочерний элемент как экземпляр родительского класса.

Writer является экземпляром дочернего класса ContentWriter. Оператор writer instanceof ContentWriter оценивается как true.

В то же время ContentWriter является дочерним классом User. Таким образом, writer instanceof User также оценивает как true.

Что если вы хотите определить точный класс экземпляра? Вы можете использовать свойство constructor и сравнить его непосредственно с классом:

7. Классы и прототипы

Я должен сказать, что синтаксис класса в JavaScript отлично справляется с абстрагированием от прототипного наследования. Для описания синтаксиса class я даже не использовал термин prototype.

Но внутри классы построены на основе прототипного наследования. Каждый класс является функцией и создает экземпляр при вызове в качестве конструктора.

Следующие два фрагмента кода эквивалентны.

Версия с прототипом:

Синтаксис класса намного проще в работе, если вы знакомы с классическим механизмом наследования языков Java или Swift.

В любом случае, даже если вы используете синтаксис класса в JavaScript, я рекомендую вам хорошо разбираться с прототипным наследованием (prototypal inheritance).

8. Наличие возможностей класса

Свойство классов, рассмотрены в этом посте, были внедрены в ES2015 а так же новыми предложениям (proposals) находящимися на этапе 3.

В конце 2019 года функции класса разделяются на:

9. Заключение

Классы JavaScript инициализируют экземпляры конструкторами, определяют поля и методы. Вы можете прикрепить поля и методы даже к самому классу, используя ключевое слово static.

Наследование реализуется с помощью ключевого слова extends: вы можете легко создать дочерний класс из родительского. Ключевое слово super используется для доступа к родительскому классу из дочернего класса.

Чтобы воспользоваться преимуществами инкапсуляции, делайте поля и методы приватными, чтобы скрыть внутренние детали ваших классов. Имена приватных полей и методов должны начинаться с #.

Классы в JavaScript становятся все более удобными в использовании.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *