Уроки JavaScript – ознакомление с классами (часть 2)

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

Предыдущая статья цикла: Ознакомление с классами в JavaScript (часть 1)

 

 

JavaScript классы и поля классов

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

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

 

 

Открытые поля и методы

Одна вещь, которую вы должны знать и помнить на будущее, — это то, что когда вы создаете эти поля, все они становятся «общедоступными» по умолчанию. Это означает, что все эти поля будут доступны как изнутри, так и снаружи класса. Вы сможете получить к ним доступ и изменить их, при желании. То же самое относится и к методам.

<script>   class Vehicle {    // Объявляем все свойства напрямую, как открытые по умолчанию    name = 'Автомобиль';    condition = 'Б/у';    speed = 220;    // Все методы ниже созданы как публичные по умолчанию    vehicleName(name) {     this.name = name;    }    vehicleCondition(condition) {     this.condition = condition;    }    vehicleSpeed(speed) {     this.speed = speed;    }   }  </script>  

 



 

Закрытые поля и методы

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

Когда вы объявляете какое-либо свойство класса как закрытое, вы можете получить к нему доступ только внутри этого класса. Итак, если вы хотите получить доступ к этому свойству и изменить его, вы можете создать методы внутри этого класса и использовать их для изменения этих свойств. Синтаксис для создания закрытых полей прост, достаточно указать перед именем свойства #. Потом не забудьте использовать #, когда вам нужно будет получить доступ к такому свойству.

 

Класс с открытыми и закрытыми свойствами

<script>   class MyClass {    // создаем открытое свойство    foo = 'Это открытое свойство';    // Создаем закрытое свойство. Не забудьте начать с #    #bar = 'Это закрытое свойство';    // Добавляем метод для доступа к публичному свойству foo    getFoo() {     return this.foo;    }    // Добавляем метод для доступа к закрытому свойству bar    getBar() {     // Не забудьте использовать полное имя свойства, включая #     return this.#bar;    }    // Добавляем метод для изменения закрытого свойства bar    changeBar(text) {     // Не забудьте использовать полное имя свойства, включая #     this.#bar = text;    }   }   // Создаем экземпляр класса MyClass   const classInstanceOne = new MyClass();   // Попробуем увидеть в логе открытое свойство foo с помощью метода getFoo()   console.log(classInstanceOne.getFoo()); // Вывод: Это открытое свойство   // Попробуем увидеть в логе закрытое свойство bar с помощью метода getBar()   console.log(classInstanceOne.getBar()); // Вывод: Это закрытое свойство   // Попробуем увидеть в логе открытое свойство foo напрямую   console.log(classInstanceOne.foo); // Вывод: Это открытое свойство   // Попробуем увидеть в логе закрытое свойство bar напрямую   console.log(classInstanceOne.#bar); // Вывод: SyntaxError: Undefined private field undefined: must be declared in an enclosing class   // Используем метод changeBar, чтобы изменить закрытое свойство bar   classInstanceOne.changeBar('Это новый текст');   // Попробуем снова увидеть в логе закрытое свойство bar с методом getBar()   console.log(classInstanceOne.getBar()); // Вывод: Это новый текст  </script>  

 

 

Подобно общедоступным методам, вы также можете создавать закрытые методы. Правила те же, что и для закрытых свойств (или полей). Эти методы видны только внутри класса. Вы не можете получить к ним доступ или использовать их извне. Здесь синтаксис такой же. Нужно указывать названием метода начиная с #.

 

 

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

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

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

<script>   // Класс со статическим свойством и методом   class MyClass {    // Объявляем статическое свойство    static foo = 'Статическое свойство';    // Объявляем статический метод    static getFoo() {     // Возвращаем значение статического свойства foo     return MyClass.foo;    }   }   // Попробуем получить доступ к статическому свойству foo непосредственно в MyClass   console.log(MyClass.foo); // Вывод: Статическое свойство   // Попробуем получить доступ к статическому свойству foo, используя статический метод getFoo() в MyClass   console.log(MyClass.getFoo()); // Вывод: Статическое свойство   // Создадим экземпляр класса MyClass   const myClassInstance = new MyClass();   // Попробуем получить доступ к статическому свойству foo в myClassInstance   console.log(myClassInstance.getFoo()); // Вывод: TypeError: myClassInstance.getFoo is not a function   console.log(myClassInstance.foo); // Вывод: undefined  </script>  

 

 

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

 

 

 

Геттер и сеттер методы доступа

Другим относительно новым дополнением к классам JavaScript являются методы доступа getter (геттер) и setter (сеттер). Они были введены в ECMAScript 5 и они, на самом деле, очень просты для понимания и использования.

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

Геттер методы – это методы, которые вы используете, когда хотите получить доступ и/или вернуть значение свойства. Например, если вы хотите получить доступ к некоторому значению свойства, вам не нужно просто возвращать (return) это значение. Вместо этого вы можете использовать метод геттера, чтобы определить «пользовательский» вывод, такой как короткое сообщение, которое содержит значение этого свойства.

Когда вы хотите создать метод доступа к сеттеру, перед именем метода ставится префикс set. Когда вы хотите создать метод доступа к геттеру, вы используете префикс get.

<script>   class User {    constructor(username) {     // Это вызовет сеттер     this.username = username;    }    // Создаем геттер для свойства username    get username() {     console.log(`Ваш юзернейм ${this._username}.`);    }    // Создаем сеттер для свойства username    set username(newUsername) {     // Проверяем длину newUsername     if (newUsername.length === 0) {      // Показать сообщение, если имя пользователя слишком короткое      console.log('Имя слишком короткое');     }     // В противном случае присваиваем newUsername и используйте его в качестве значения для юзернейм     this._username = newUsername;    }   }   // Создаем экземпляр класса User   const userOne = new User('Степан');   // Получаем доступ к свойству username пользователя userOne. Это автоматически вызовет геттер метод для свойства username   userOne.username; // Вывод: Ваш юзернейм Степан   // Попробуем создать экземпляр User без имени пользователя. Это автоматически вызовет сеттер метод для свойства username   const userTwo = new User(''); // Имя слишком короткое  </script>  

 

 

В приведенном выше примере мы создали геттер и сеттер методы для свойства username. Как видите, мы добавили перед свойством username нижнее подчеркивание (_). Без этого каждый раз, когда вызывается метод get или set, это вызывает переполнение стека. Это означает, что будет вызван get, и он вызовет геттер снова и снова. Это создаст бесконечный цикл.

Две вещи о геттер и сеттер функциях, которые вы должны знать:

  • Во-первых, вы не вызываете их явно. Все, что вам нужно сделать, это просто определить их. JavaScript сделает всю остальную работу за вас.
  • Во-вторых, setter и getter метод должен иметь то же имя, что и свойство, которое вы хотите, чтобы они обрабатывали.

Вот почему в приведенном выше примере мы использовали username в качестве имени для наших методов геттера и сеттера. Это, наряду с ключевыми словами get и set, сообщает JavaScript, что нужно делать, и с каким свойством это делать. Поэтому убедитесь, что имена методов setter и getter всегда совпадают с именами свойств.

 

 

 

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

Спасибо, что читаете нас!