Proxy ဆိုတာ အမှန်တော့ Object တစ်မျိုးပါပဲ။ သူက တစ်ခြား Object တွေကို အုပ် (wrap) ပြီး ကိုယ်လိုချင်တဲ့ Custom Operation/Behavior ဖြစ်အောင် Intercept လုပ်လို့ရစေပါတယ်။ ပြောချင်တာက ကိုယ့်ရှိပြီးသား Object မှာ ရှိတဲ့ Attribute တွေ၊ Method တွေကို ကိုယ်လိုချင်သလို ပြုပြင်ပြောင်းလဲလို့ရတဲ့အပြင် မရှိသေးရင်လဲ handle လုပ်နိုင်ပါသေးတယ်။ Proxy ကို ဘယ်တွေမှာ သုံးလဲဆိုရင် Browser Library / Framework တွေမှာ သုံးလေ့ရှိကြပြီး တစ်ခြားနေရာတွေမှာလဲ သင့်လျော်သလိုသုံးနိုင်ပါတယ်။ (make sense ဖြစ်ရင်ပေါ့ဗျာ၊ မဟုတ်ရင်တော့ နည်းနည်း Overkill ဖြစ်စေနိုင်ပါတယ်။)
Proxy တစ်ခုဘယ်လို ဆောက်လဲဆိုတော့
let proxy = new Proxy(target, handler);
- target => ဆိုတာက ကိုယ် wrap (အုပ်) မယ့် Object ပဲဗျ။ ဆိုတော့ JS မှာ almost everything (Functions, Arrays, etc.) is Object ဖြစ်တဲ့ အတွက်ကြောင့် ဘာမဆိုဖြစ်လို့ရတယ်ဆိုတဲ့ သဘောပါပဲ။
- handler => ဆိုတာကျတော့ Proxy ကို ကိုယ်ဖြစ်ချင်တဲ့ဟာတွေ define/handle လုပ်ပေးတဲ့ configuration object တစ်ခုပါပဲ။ သူ့ထဲမှာ trap လို့ခေါ်တဲ့ intercept လုပ်မယ့် method တွေရှိပါမယ်။ ဥပမာ “get” trap ဆိုတဲ့ object တစ်ခုရဲ့ property ကို read တဲ့ဟာပေါ့။ ပုံမှန် read ရင် နှစ်မျိုး ရှိတာသိမယ်ထင်ပါတယ်။
person.age;
(သို့)
person[‘age’]
အဲ့ဒီ person ဆိုတဲ့ object ကို proxy ခံပြီးရင် get trap ကို ကိုယ်ကြိုက်သလို စီမံလို့ရပါတယ်။ အောက်က code ကို ကြည့်လိုက်ရင် ပိုပြီး မြင်သာပါလိမ့်မယ်။
// Proxy မခံထားသေးသော သာမန် person object
const person = {
age: 25,
};
// 25 ဆိုပြီး output ထွက်ပါလိမ့်မယ်
console.log('Age: ', person.age);
// ======================================= //
// အရင်ဆုံး Handler လေး စရေးပါမယ်
// ဒီထဲမှာ get trap ကို custom define ပါမယ်
const handler = {
get: (targetObj, property) => {
// age ကို ကြားထဲကနေ ၂ဆ တိုးလိုက်ပါမယ် xD
return property in targetObj ? targetObj[property] * 2 : 'ဘာတေလဲ';
},
};
// person ကို ဒီလို Proxy ခံလိုက်ပါမယ်
const proxifiedPerson = new Proxy(person, handler);
// ဒါဆို output က 50 ဆိုပြီး ထွက်ပါလိမ့်မယ်
console.log('Age: ', proxifiedPerson.age);
// တကယ်လို့ မရှိတဲ့ property ကို လာတောင်းရင်
console.log('FA လား? ', proxifiedPerson.isFA);
အကယ်၍ trap မရှိဘူးဆိုရင် wrapped object ကို ပဲ forward လုပ်သွားမှာဖြစ်ပါတယ်။ Proxy ဆိုတာ transparent wrapper ပဲဖြစ်တဲ့အတွက်ကြောင့် မို့လို့ ဒီလို forward လုပ်နိုင်တာပါ။ ရနိုင်တဲ့ trap အပြည့်အစုံကို ဒီ link မှာကြည့်နိုင်ပါတယ်။
Reflect
Meta Programming ရဲ့ Proxy လို နောက်ထပ် အရေးပါတဲ့ Reflect ဆိုတဲ့ feature တစ်ခုရှိပါသေးတယ်။ သူ့ကို Proxy နဲ့ အတူ တွဲသုံးလေ့ ရှိပါတယ်။ Reflect ကို Proxy လိုပဲ သုံးနိုင်ပါတယ်။ ထူးခြားတာက သူက တိုက်ရိုက်ခေါ်လို့မရတဲ့ internal method မျိုးတွေကို လှမ်းသုံးလို့ ရအောင်လုပ်ပေးပါတယ်။ ဥပမာ proxifiedPerson.get(‘age’) ၊ ဒါမှမဟုတ် proxifiedPerson.set(‘age’, 34) လို့ ခေါ်လို့မရပါဘူး။ Proxy ထဲမှာတင် ဒီလို access လုပ်ချင်လာပြီဆိုရင်တော့ Reflect ကို သုံးပြီး original target object ဆီကို forward လုပ်နိုင်ပါတယ်။
// Proxy မခံထားသေးသော သာမန် person object
let person = {
age: 25,
};
// Reflect ကိုသုံးပြီး forward လုပ်ထားပါတယ်
const handler = {
get: (targetObj, property, receiver) => {
return Reflect.get(targetObj, property, receiver);
},
set: (targetObj, property, value, receiver) => {
return Reflect.set(targetObj, property, value, receiver);
},
};
person = new Proxy(person, handler);
// output က 25 ထွက်ပါမယ်
console.log('person Age: ', person.age);
// person age ကို 30 ထားလိုက်ပါမယ်
person.age = '30';
// output က 30 ထွက်ပါမယ်
console.log('person Age: ', person.age);
Proxy ကို သုံးလို့ရတဲ့ နေရာတွေက အများကြီးပါပဲ။
- Setter method တွေကို Validation လုပ်တာတွေ
- DOM manipulation တွေ၊ စတာတွေ အပြင် သုံးလို့ရတဲ့နေရာတွေ အများကြီးပါ။
Example အနေနဲ့ JavaScript Array ကို python မှာလိုမျိုး negative index နဲ့ access လုပ်ရင် နောက်ဆုံးက array item ကို return ပြန်တာမျိုးရေးပြထားပါတယ်။ ဥပမာ array[-1] ဆို နောက်ဆုံး၊ array[-2] ဆို နောက်ဆုံးရဲ့ ရှေ့က item စသည်ဖြင့်ပေါ့ဗျာ။
let myArray = ['one', 'two', 'three'];
const handler = {
get: (targetObj, property, receiver) => {
if (property < 0) {
property = targetObj.length + parseInt(property);
}
return Reflect.get(targetObj, property, receiver);
},
};
myArray = new Proxy(myArray, handler);
console.log(myArray[-1]); // three
console.log(myArray[-2]); // two
ဒီလောက်ဆိုရင်တော့ Proxy and Reflect အကြောင်း intro အနေနဲ့ နည်းနည်း တီးမိခေါက်မိ ဖြစ်သွားမယ်ထင်ပါတယ်။ တစ်ခုခု မရှင်းတာတို့၊ သိချင်တဲ့ topic တို့၊ ဒါမှမဟုတ် feedback ပေးချင်တာတွေကို page inbox ကနေပေးပို့နိုင်ပါတယ်ဗျ။