Klasslar

Maxfiy va himoyalangan xossalar

Obyektga yo'naltirilgan dasturlashning eng muhim tamoyillaridan biri โ€” inkapsulyatsiya: ichki tafsilotlarni tashqi kodda yashirish. Bu murakkablikni kamaytiradi va kodni xavfsizroq qiladi.

Ichki va tashqi interfeys

Obyektga yo'naltirilgan dasturlashda xossa va metodlar ikki turga bo'linadi:

JavaScript'da a'zolikni belgilashning ikki asosiy usuli bor: protected (himoyalangan, konvensiya) va private (maxfiy, til darajasida). Ularni ko'rib chiqamiz.

protected โ€” konvensiya (_ old qo'shimchasi)

Himoyalangan (protected) xossalar odatda nom oldiga pastki chiziq _ qo'yish orqali belgilanadi. Bu til darajasida majburiy emas โ€” bu shunchaki dasturchilar orasidagi kelishuv (konvensiya).

protected-water.js
// natija shu yerda chiqadi

Bu yerda _waterAmount โ€” ichki holat, u get/set orqali nazorat qilinadi. Manfiy qiymatni o'rnatishga urinsak, u avtomatik 0 ga tenglashadi. Shu tariqa biz noto'g'ri holatdan himoyalanamiz.

_ old qo'shimchasi โ€” bu faqat kelishuv. Yaxshi dasturchi _li xossalarga tashqaridan tegmaydi. Ammo texnik jihatdan bunga hech narsa to'sqinlik qilmaydi โ€” machine._waterAmount = -10 deb yozish baribir mumkin.

Faqat o'qish uchun (read-only) xossalar

Ba'zi xossalarni yaratilgandan keyin o'zgartirib bo'lmaydigan qilishimiz mumkin. Buning uchun faqat get yozamiz, setni esa yozmaymiz:

protected-readonly.js
// natija shu yerda chiqadi

private โ€” # maydonlar

Zamonaviy JavaScript'da haqiqiy maxfiy (private) maydonlar mavjud. Ular nom oldiga # belgisi qo'yish orqali yaratiladi. Bunday maydonlar faqat shu klass ichidan ko'rinadi โ€” bu til darajasida ta'minlanadi:

private-fields.js
// natija shu yerda chiqadi

Endi tashqaridan #waterLimit yoki #fixWaterAmountga murojaat qilib bo'lmaydi โ€” bu sintaktik xato beradi:

let machine = new CoffeeMachine();

// tashqaridan kirish mumkin emas:
machine.#waterLimit = 1000;
// SyntaxError: Private field '#waterLimit'
// must be declared in an enclosing class
Maxfiy maydonlar odatdagi maydonlar bilan ziddiyatlashmaydi. Ya'ni bir klassda ham #waterAmount (maxfiy), ham waterAmount (oddiy) bo'lishi mumkin โ€” ular butunlay alohida maydonlar.

private + getter/setter bilan to'liq himoya

Eng ishonchli usul โ€” maxfiy maydonni # bilan e'lon qilib, unga faqat getter/setter orqali kirish. Shunda ma'lumot ham yashiringan, ham nazorat ostida bo'ladi:

private-getset.js
// natija shu yerda chiqadi

private maydonlar meros olinmaydi

Muhim cheklov: maxfiy # maydonlar meros olgan klasslarda ko'rinmaydi. Agar himoyalangan, lekin merosxo'rlarga ochiq bo'lishini istasangiz, _ konvensiyasidan foydalaning.

private-inherit.js
// natija shu yerda chiqadi

Nima uchun inkapsulyatsiya kerak?

Inkapsulyatsiyaning katta afzalliklari bor:

Yangi loyihalarda haqiqiy maxfiylik uchun # maydonlarini ishlatish tavsiya etiladi. Eski kodlarni qo'llab-quvvatlashda esa _ konvensiyasi hali ham keng tarqalgan.

Xulosa