Proxy va Reflect
Proxy boshqa obyektni "o'rab" oladi va u bilan bog'liq amallarni โ o'qish, yozish, o'chirish kabi โ ushlab qolib, o'zgartirish imkonini beradi. Reflect esa aynan shu amallarni past darajada bajarish uchun standart funksiyalar to'plamidir. Ular ko'pincha juft holda ishlatiladi.
Proxy sintaksisi
Proxy quyidagicha yaratiladi:
let proxy = new Proxy(target, handler);
targetโ o'raladigan asl obyekt (istalgan obyekt, jumladan funksiya yoki massiv);handlerโ tuzoqlar (traps) to'plami bo'lgan obyekt. Har bir tuzoq ma'lum amalni ushlab qoladi.
Agar handler bo'sh bo'lsa, proxy targetga shaffof o'rab beradi โ barcha amallar to'g'ridan-to'g'ri asl obyektga o'tadi:
get tuzog'i: o'qishni ushlab qolish
Eng ko'p ishlatiladigan tuzoqlar โ get (xususiyat o'qishda) va set (xususiyat yozishda). get(target, property, receiver) chaqiriladi:
targetโ asl obyekt;propertyโ o'qilayotgan xususiyat nomi;receiverโ proxyning o'zi (yoki undan meros olgan obyekt).
Mana mavjud bo'lmagan kalitlar uchun standart qiymat qaytaruvchi misol. Odatda mavjud bo'lmagan kalit undefined beradi, biz esa 0 qaytaramiz:
set tuzog'i: validatsiya
set(target, property, value, receiver) yozishni ushlab qoladi. U albatta qiymat qabul qilinganda true, rad etilganda false qaytarishi kerak. false qaytsa (yoki qat'iy rejimda) TypeError yuzaga keladi.
Massivga faqat butun son qo'shishga ruxsat beruvchi validatsiya:
setda return trueni unutmang โ aks holda amal muvaffaqiyatsiz deb hisoblanadi va xatolik chiqadi.has va deleteProperty tuzoqlari
has(target, property) โ in operatorini ushlab qoladi. Quyida range obyekti oraliqqa tegishlilikni tekshiradi:
deleteProperty(target, property) โ deleteni ushlab qoladi. Masalan, _ bilan boshlangan "maxfiy" xususiyatlarni o'chirishni taqiqlaymiz:
Reflect API
Reflect โ obyekt ustidagi ichki amallarni chaqirish uchun standart obyekt. Uning har bir metodi biror tuzoq bilan mos keladi: Reflect.get, Reflect.set, Reflect.has, Reflect.deleteProperty va hokazo.
Tuzoq ichida asl amalni bajarishning eng to'g'ri usuli โ mos Reflect metodini chaqirish. Bu receiverni to'g'ri uzatadi va meros (inheritance) holatlarida ham xatosiz ishlaydi:
target[prop] deb emas, Reflect.get(target, prop, receiver) deb bajaring. Bu receiver orqali thisni to'g'ri saqlaydi.Cheklovlar
Proxy kuchli, lekin ba'zi cheklovlari bor:
- Ba'zi ichki obyektlar (masalan
Map,Set,Date) ichki slotlarga ega โ ularni to'g'ridan-to'g'ri proxylash muammo tug'diradi. Yechim: metodnibindqilish; - Xususiy sinf maydonlari (
#field) ham ichki slotdan foydalanadi; - Proxy asl obyektdan biroz sekinroq ishlaydi โ juda tez-tez chaqiriladigan joylarda buni hisobga oling.
Xulosa
new Proxy(target, handler)โ obyekt ustidagi amallarni ushlab qolish uchun "o'rovchi";- Asosiy tuzoqlar:
get,set,has,deletePropertyva boshqalar; settuzog'itrue/falseqaytarishi shart;Reflectโ tuzoq ichida asl amalni to'g'ri bajarish uchun ishlatiladi;- Qo'llanilishi: validatsiya, standart qiymat, kirishni cheklash, kuzatuv (logging).