Încapsularea proprietăților - Get-teri și Set-teri
Încapsularea este unul dintre conceptele cheie ale programării orientate pe obiect și reprezintă ascunderea stării unui obiect pentru a menține integritatea datelor prin evitarea accesului direct din exterior. În mod implicit, toate proprietățile obiectelor sunt publice și accesibile, iar noi putem să le accesăm din orice parte a programului.
function User(uName, uAge) {
this.name = uName;
this.age = uAge;
this.print = function(){
console.log(`Name: ${this.name} Age: ${this.age}`);
};
}
const tom = new User("Tom", 39);
tom.age = 11500;
tom.print(); // Name: Tom Age: 11500
Cu toate acestea, un astfel de mod de acces poate fi nedorit. De exemplu, în exemplul de mai sus, proprietății age, care reprezintă vârsta, i-am putea atribui diferite valori, inclusiv cele inadmisibile.
Cu toate acestea, putem să le ascundem de accesul din exterior. Pentru aceasta, proprietatea este definită ca o variabilă locală/constantă:
function User(uName, uAge) {
this.name = uName;
let _age = uAge;
this.print = function(){
console.log(`Name: ${this.name} Age: ${_age}`);
};
}
const tom = new User("Tom", 39);
tom._age = 11500;
tom.print(); // Name: Tom Age: 39
În constructorul User, este declarată o variabilă locală _age în locul proprietății age:
let _age = uAge;
De obicei, numele variabilelor locale în constructori încep cu un caracter de subliniere. Această variabilă poate să primească date din parametrii constructorului și poate fi utilizată în funcțiile din interiorul constructorului. Cu toate acestea, nu se poate accesa din exterior:
tom._age = 11500;
Aici, pentru obiectul tom, se definește o nouă proprietate care se numește la fel ca și variabila _age. Cu toate acestea, această proprietate _age nu va avea niciun efect asupra variabilei locale _age, așa cum putem vedea din afișarea consolei în metoda print.
Get-teri și Set-teri
Mai sus, am ascuns valoarea vârstei în variabila locală _age, însă uneori este necesară totuși o anumită formă de acces, de exemplu, pentru a afișa în consolă sau pentru a modifica. În acest caz, putem defini metode speciale de acces - get-ter (pentru a obține valoarea) și set-ter (pentru a modifica valoarea).
function User(userName, userAge) {
this.name = userName;
let _age = userAge;
// getter - return the value of the variable
this.getAge = function() { return _age; }
// setter - set the value of the variable
this.setAge = function(age) {
if(age > 0 && age < 110){ //dacă varsta este mai mare ca 0 și mai mică ca 110
_age = age;
} else {
console.log("Invalid value");
}
}
this.print = function(){
console.log(`Name: ${this.name} Age: ${_age}`);
};
}
const tom = new User("Tom", 39);
//obține valoarea
console.log(tom.getAge()) // 39
// setează o valoare nouă
tom.setAge(22);
console.log(tom.getAge()) // 22
tom.setAge(11500); // Invalid value
console.log(tom.getAge()) // 22
Pentru a lucra cu vârsta utilizatorului din exterior, sunt definite două metode. Metoda getAge() este destinată obținerii valorii variabilei _age. Această metodă mai este cunoscută și sub denumirea de getter. A doua metodă - setAge, care mai este numită și setter, este destinată setării valorii variabilei _age.
Avantajul acestui abordaj constă în faptul că avem un control mai mare asupra accesului la valoarea _age. De exemplu, putem verifica anumite condiții asociate, așa cum este cazul verificării tipului de valoare (aceasta trebuie să reprezinte un număr), valoarea în sine (vârsta nu poate fi mai mică de 0).
Trebuie de menționat că JavaScript oferă, de asemenea, construcții speciale pentru crearea getterelor și setterelor - get și set, respectiv. Cu toate acestea, în contextul funcțiilor constructor, ele nu au un sens mare, așa că vor fi discutate mai detaliat.