Классы в JavaScript

Ранее, до появления версии EcmaScript 6 классы в JavaScript реализовывались через создание функции-конструктора объектов. Эта функция и представляла собой класс. Она позволяла создавать приватные, публичные и статические члены класса без явного указания модификатора доступа.

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

Появление EcmaScript 6 изменил синтаксис создания классов в лучшую сторону. Стандарт позволил JavaScript программистам проектировать классы как это делается в большинстве ООП языках, через ключевое слово «class». При этом, старый стандарт никуда не делся.

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

Что такое классы?

Класс — это шаблон для создания объектов на основе спроектированного класса. Все публичные свойства и методы, которые объявлены в классе передаются вновь созданным объектам. Свойства и методы класса — это переменные и функции, которые инкапсулированы в блоке класса. Свойства и методы вызываются через ссылку — имя переменной объекта, созданного на основе класса.

Класс состоит из следующих элементов:

  • class Name{} — объявление класса через ключевое слово class, имя Name пишется с большой буквы и может быть произвольным — можно и с маленькой но заглавная буква ставится по правилам хорошего тона), а блок «{}» является границей описания класса;
  • публичные свойства — переменные, которые могут хранить примитивные значения, массивы, объекты и списки, доступ к свойствам осуществляется через имя объекта;
  • публичные методы — функции класса, которые, как и свойства, скрыты в объектах от глобального контекста;
  • приватные методы и свойства — не могут быть доступны напрямую через имя объекта, что вызовет ошибку, они доступны лишь на уровне класса, то есть — могут использоваться только публичными методами класса и помечаются модификатором «#»;
  • статические свойства и методы — обычные функции и переменные класса, объявленные с модификатором static, не являются экземплярами объектов, но класса, доступ к ним осуществляется через имя класса, а не объекта;
  • конструктор — является функцией-конструктором объектов, она может принимать различные параметры для редактирования свойств для различных объектов.

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

class Human{

}

Добавим свойства в наш класс:

class Human{
height: 180; // свойство
weight: 75;

// добавим метод
show_characteristics(){
alert(this.height+» «+this.weight);
}
}
// создадим объект

var Dmitry = new Human(); // создали объект, конструктором по умолчанию
alert(Dmitry.height); // 180 — доступ к свойству осуществляется через имя объекта
show_characteristics(); 180 75 — через имя объекта

Обратите внимание, что в теле метода присутствует слово this. Оно обозначает текущий объект, то есть — оно является заменой имени объекта. This — этот объект. К примеру, для объекта «Саши» и «Пети» свой this, один раз определенный в классе, но у каждого объекта this — имя переменной объекта. Кстати переменная, которая определяется при создании объекта является ссылкой на кучу — область памяти, где хранятся все объекты.

Определим в объекте конструктор

class Car{
model; // значения свойств будут определены конструктором
year;

constructor(a, b){
this.model = a;
this.year = b;
}
}

// Создадим объект через конструктор

var ford = new Car(«Ford», 2010);
alert(ford.model); // Ford
alert(ford.year); // 2010

// еще объекты
var lada = new Car(«Lada», 1990);
var volga = new Car(«Volga», 1980);

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

В EcmaScript 6 появилась простая возможность установить приватность методов и свойств. Для этого достаточно поставить символ «#» перед именем метода или свойства без пробела: #someMethod(){}, #someProperty = 12. Приватные свойства или методы не могут быть доступны через имя объекта или класс. Они доступны только в контексте класса. Поэтому их используют внутри публичных или статических методов.

Пример:

class Device{
width;
#height; // объявили приватное свойство
constructor(a, b){
this.width = a;
this.height = b; // задаем значение приватному свойству через конструктор
}
show_info(){
alert(this.height); // выводим значение приватного свойства
}
}

// создадим объект и проверим как можно получить значение приватного свойства

var phone = new Device(10, 20);
alert(phone.width); // 10 — ничего не произошло, значение вывелось без проблем
alert(phone.height); // ошибка! — нельзя получить доступ к приватному свойству через имя объекта
phone.show_info(); // 20 — значение приватного свойства выведено через публичный метод

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

Пример:

class Device{
width;
height;
constructor(a, b){
this.width = a;
this.height = b;
}
#show_info(){ // создали приватный метод
alert(this.height);
}

get_info{ // публичный метод-обертка, который вызывает приватный метод
this.show_info();
}
}

var tablet = new Device(100, 200);
tablet.show_info(); // Ошибка! Приватный метод нельзя вызвать напрямую через объект
tablet.get_info(); // 200 — вызов публичного метода активировал вызов приватного метода и ошибки никакой нет

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

Статические свойства и методы являются экземплярами класса, но не объектов. При этом, доступ к свойствам или методам осуществляется не через имя объекта, а через имя класса. Эти экземпляры ни коем образом не относятся к объектам. Объекты могут лишь получать значения статических экземпляров, но не могут их изменять.

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

Пример:

class Device{
width;
height;
type;
static electric_count = 0; // счетчик электрических чайников
static common_count = 0; // счетчик электрических чайников
constructor(a, b, t){
this.width = a;
this.height = b;
this.type = t; // третий аргумент указывает тип чайника: электрический или обычный
if(this.t==»electric») Device.electric_count++; // если тип созданного объекта чайника является электрическим, то их счет увеличивается на один
else Device.common_count++; // если не электрический то счетчик простых увеличивается на один
}

// Теперь протестируем наши статические свойства на объектах

var phillips = new Device(20, 50, «electric»);
var samsung = new Device(21, 51, «electric»);
var common = new Device(23, 51, «common»);

console.log(phillips.electric_count); // Ошибка! Доступ к статическому экземпляру осуществляется только через имя класса
console.log(Device.electric_count); // 2 — было создано два электрочайника
console.log(Device.common_count); // 1 — обычных чайников было создано всего один

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

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

Какие еще есть возможности в ООП в JavaScript

Стоит отметить, что JavaScript до версии ES6 был прототипно-ориентированным языком программирования, а классы создавались благодаря функциям-конструкторам. Новый стандарт 2015-го года сделал язык более приближенным к ООП. Появление классов и модификаторов доступа позволило JS с легкостью реализовать такие приемы ООП как: наследование, полиморфизм, инкапсуляция.

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

ООП подарило для JavaScript возможность явно указывать модификаторы доступа для свойств и методов. Когда в функциональном стиле отделить члены класса было достаточно непросто — нужно было писать простые функции или вложенные.

Наследование также реализовывалось не совсем по людски. При копировании свойств и методов из основного класса требовалось писать непонятную конструкцию. В новом стиле JS все решает простой метод super().

Классы позволяют забыть о сложности изучения прототипов. Однако не рекомендуется тем, кто собирается программировать на JS или строить карьеру, забывать о прототипах. В серьезных проектах, потребуется знание полного языка, а не только обновлений 2015-го года. При том, что JavaScript является динамически-типизированным языком (не нужно явно указывать тип переменных), то программист избавляется от таких сложностей, как преобразование типов различных объектов, а также перегрузок операций над преобразованием типов.

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

Образовательный портал 3TY.RU
Adblock
detector