Есть два типа свойств у объекта:
data properties
-
это все обычные свойства ключ
: значение
.accessor properties
-
это уже функции которые во внешнем коде будут выглядеть как обычные свойства.// get and set
const user = {
name: 'Dima',
age:'24',
get userAge () { // ключевое слово get (мы получаем значение)
return this.age; // получаем наш возраст
},
set userAge(num){ // в пару к get идет set, он уже что то должен в себя принимать (мы устанавливаем значение)
this.age = num;
}
};
console.log(user.userAge); // при вызове мы не пишем userAge().
// геттер предпологает что внутри у нас уже есть какой то функционал и он нам позволяет работать с этим меотодом как с обычным совйством.
// Поэтому это называется свойство аксессор
console.log(user.userAge = 30);
console.log(user.userAge); // 30
Опять немного ООП
Инкапсуляция - это такое понятие в ООП. Инкапсуляция представляет собой способ скрывать состояния объекта от прямого доступа из вне. В ООП это означает, что объект хранит свое состояние в приватном порядке и только методы объекта имеют доступ для его изменений. По умолчанию все свойства объектов являются публичными, общедоступными, и мы к ним можем обратиться из любого места программы. По простому инкапсуляция это некая капсула, которая хранит данные и методы, и только эта капсула знает о деталях, мы просто пользуемся всем что есть в этой капсуле.
function User(name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log(`Имя пользователя:${this.name}, возраст:${this.age}`);
};
}
const ivan = new User('ivan', 30); // создадим новый экземпляр
console.log(ivan.name); // ivan
console.log(ivan.age); // 30
// все работает. Но так же мы можем и менять значения свойств объекта
ivan.name = 'dima';
ivan.age = 18;
ivan.say(); // dima, 18
// Для того и нужна инкапсуляция, что бы мы не могли так нагло вмешиваться в свойства.
Далее будем работать с этой же функцией. Если мы вместо свойства создадим переменную, это уже будут зачатки инкапсуляции. так как мы создали переменную, мы не можем поменять ее и даже получить. И что бы работать с такими переменными нам нужны гетер и сетер. Но немного не тот синтаксис о котором говорили ранее. Геттерами и сетарами так же называют любые методы которые позволяют получать либо устанавливать значения.
// например поменяем у нашей функции this.age на создание обычной переменной.
function User(name,age) {
this.name = name;
let userAge = age;
this.say = function() {
console.log(`Имя пользователя:${this.name}, возраст:${userAge}`);
};
}
const ivan = new User('ivan', 30);
ivan.userAge = 50; // не можем поменять. Таким образом мы просто создали свойства userAge:50
ivan.say(); // age будет 30. Наша же переменная осталась нетронутая
А таким образом обходились до методов get
и set
:
function User(name, age) {
this.name = name;
let userAge = age;
this.say = function () {
console.log(`Имя пользователя:${this.name}, возраст:${userAge}`);
};
this.getAge = function () { // создаем функцию которая возвращает нам age
return userAge;
};
this.setAge = function (age) { // функция для установки значения
if (typeof (age) === 'number' && age > 0 && age < 110) { // небольшое условие
userAge = age; // если все хорошо устанавливаем.
} else { // иначе ошибка
console.log('недопустимое значение');
}
};
}
const ivan = new User('ivan', 40);
// теперь для получения возраста у нас есть определенная функция и для того что бы его поменять тоже
console.log(ivan.getAge()); // 40
ivan.setAge(30); // меняем возраст
ivan.setAge(300); // недопустимое значение.
console.log(ivan.getAge()); // 30
ivan.say();// Имя пользователя:ivan, возраст:30
Так вот мы и получили нашу инкапсуляцию. Теперь испробуем на классе.
В классах те свойства которые нам нужно скрыть мы добавляем нижнее подчеркивание. Это не синтаксис языка, это договоренность между программистами.
Здесь мы уже будем использовать те самые методы геттер и сеттер которые изучили в начале, а то, что я писал выше как я и сказал это по сути старый вариант до get
и set
class User{
constructor(name,age) {
this.name = name;
this._age = age; // пишем _age, что значит свойство приватное.Если другой программист это увидит, он будет значть, что это приват
}
say() {
console.log(`Имя пользователя:${this.name}, возраст:${this._age}`);
}
get age() { // получаем приватное свойство
return this._age;
}
set age(age) { // метод для изменения приватного свойства.
if(typeof(age) === 'number' && age > 0 && age < 110) {
this._age = age;
} else {
console.log('недопустимое значение');
}
}
}
const ivan = new User('ivan', 30);
console.log(ivan.age ); // 30
ivan.age = 99; // меняем свойство
console.log(ivan.age ); // 99
ivan.age = 112; // недопустимое значение
ivan.say(); // Имя пользователя:ivan, возраст:99
Ну вот и все. По сути все тоже самое, что и когда мы создавали свои функции, для получения и установки. Только это современный синтаксис с get и set. Теперь у нас есть отдельный метод, для изменеия значения и напрямую как раньше сделать это нельзя.