Getter va setterlar
Obyekt xossalari ikki turga bo'linadi. Birinchisi โ biz odatda ishlatadigan ma'lumot xossalari (data properties). Ikkinchisi โ yangi tur: aksessor xossalari (accessor properties). Ular aslida qiymatni o'qish va yozishni boshqaradigan funksiyalardir, lekin tashqaridan oddiy xossaga o'xshaydi.
Getter va setter nima?
Aksessor xossalari ikkita maxsus metod bilan ifodalanadi:
- getter โ
getso'zi bilan belgilanadi; xossani o'qiganimizda ishga tushadi va qiymat qaytaradi; - setter โ
setso'zi bilan belgilanadi; xossaga qiymat yozganimizda ishga tushadi va argument sifatida yangi qiymatni oladi.
Tashqi kod uchun aksessor xossa oddiy xossaga o'xshaydi: siz obj.propName deb o'qiysiz va obj.propName = value deb yozasiz โ qavslar yo'q, xuddi oddiy xossadek. Ammo ostida funksiyalar ishlaydi.
Obyekt literalida getter va setter
Obyekt literalida ular get va set kalit so'zlari orqali e'lon qilinadi:
let obj = {
get propName() {
// obj.propName o'qilganda ishlaydi
},
set propName(value) {
// obj.propName = value bajarilganda ishlaydi
}
};
Amaliy misol: fullName aksessori name va surnamedan to'liq ismni hisoblab beradi:
E'tibor bering: user.fullName โ bu funksiya chaqiruvi emas (qavslar yo'q), lekin baribir get fullName metodi ishga tushdi. Bu getterning kuchi โ u xossaga o'xshab ishlaydi.
fullNameda faqat getter bor. Agar unga qiymat yozmoqchi bo'lsak โ user.fullName = "..." โ xatolik yuzaga keladi (yoki sokin rejimda e'tiborsiz qoladi), chunki setter mavjud emas.Setter qo'shish
Endi fullNamega yozishni ham qo'llab-quvvatlash uchun setter qo'shamiz. U kelgan qatorni bo'sh joy bo'yicha ajratib, name va surnameni yangilaydi:
Natijada bizda fullName "virtual" xossasi bor: uni o'qish ham, yozish ham mumkin, garchi u obyektda alohida saqlanmasa ham. U har safar name va surnamedan hisoblanadi.
fullNameni ishlatadi, ichkarida esa ma'lumot name va surnameda saqlanadi.Aksessor deskriptorlari
Aksessor xossalarining deskriptori ma'lumot xossalaridan farq qiladi. Unda value va writable o'rniga get va set funksiyalari bo'ladi. Deskriptor kalitlari:
- get โ argumentsiz funksiya, xossa o'qilganda ishlaydi;
- set โ bitta argumentli funksiya, xossaga yozilganda ishlaydi;
- enumerable โ ma'lumot xossalaridagi kabi;
- configurable โ ma'lumot xossalaridagi kabi.
get/set), ham ma'lumot (value/writable) bo'la olmaydi. Agar deskriptorda ham get, ham value ko'rsatsangiz, xatolik yuzaga keladi.Object.defineProperty bilan getter/setter
Aksessor xossani Object.defineProperty orqali ham e'lon qilish mumkin. Bu obyekt yaratilgandan keyin xossa qo'shish kerak bo'lganda foydali:
Aksessorlar validatsiya uchun
Getter/setterlarning eng foydali qo'llanishlaridan biri โ qiymatni tekshirish (validatsiya). Setter orqali biz noto'g'ri qiymat yozilishining oldini olamiz.
Quyidagi misolda age uchun setter salbiy qiymatni rad etadi. Haqiqiy ma'lumot esa "maxfiy" _age xossasida saqlanadi:
_age ismidagi ostki chiziq (underscore) โ bu shartli kelishuv. U xossa "ichki", to'g'ridan-to'g'ri chetdan tegilmasligi kerak degan ma'noni bildiradi. Bu texnik cheklov emas, balki dasturchilar orasidagi urf-odat.Aksessorlar โ moslashuvchanlik uchun
Getter/setterlar kodni kelajakda o'zgartirishni osonlashtiradi. Aytaylik, boshida name oddiy ma'lumot xossasi edi. Keyinchalik ismning uzunligini cheklash kerak bo'lib qoldi. Butun kodni o'zgartirish o'rniga, biz shunchaki nomni _namega o'zgartirib, ustiga tekshiruvchi setter qo'yamiz:
Muhimi: tashqi kod hali ham user.name deb yozadi va o'qiydi โ interfeys o'zgarmadi. Faqat ichki mantiq kuchaydi. Bu โ getter/setterlarning katta afzalligi.
Hisoblangan (computed) xossa
Getterlar obyektda saqlanmaydigan, boshqa qiymatlardan hisoblanadigan xossalar yaratish uchun ideal. Masalan, to'rtburchakning yuzasi tomonlaridan har safar hisoblab beriladi:
areani oddiy xossa qilib qo'ymaganimiz muhim: agar shunday qilsak, width o'zgarganda area eskirib qolardi. Getter esa har safar yangi qiymatni hisoblab beradi โ u har doim dolzarb.Xulosa
- Xossalar ikki turga bo'linadi: ma'lumot xossalari va aksessor xossalari (getter/setter);
- Getter โ
getbilan belgilanadi, xossa o'qilganda ishlaydi; setter โsetbilan, xossaga yozilganda ishlaydi; - Tashqaridan ular oddiy xossaga o'xshaydi:
obj.propvaobj.prop = value; - Ularni obyekt literalida (
get/setso'zlari) yokiObject.definePropertyorqali e'lon qilish mumkin; - Asosiy foydasi: validatsiya (noto'g'ri qiymatni rad etish), hisoblangan xossalar (masalan,
fullName,area) va moslashuvchanlik (interfeysni buzmasdan mantiqni o'zgartirish).