JavaScript ရဲ့closures မှာ အတွင်း function (inner function) က သူ့ကို ဖုံထားတဲ့ (enclosing function) အပြင် function ရဲ့ variable ကို access လုပ်နိုင်ပါတယ် ။ တစ်နည်းအားဖြင့် အတွင်း function (inner function) က အပြင်ဖုံးထားတဲ့ function (enclosing function) execute ဖြစ်ပြီးတဲ့အခါ အဲ့ဒီ enclosing function ရဲ့ scope chain ရဲ့ မူလအခြေနေကို ထိန်းသိမ်းပေးနိုင်တာကြောင့် အဲ့ဒီ enclosing function ရဲ့ variable တွေကို လည်း access လုပ်နိုင်ပါတယ်။
အပေါ်က ဥပမာအရဆိုရင် inner() function က b = 10 ကို outer() function execution ဖြစ်သွားလည်း b= 10 ဆိုပြီးတော့ပဲ မူလအခြေနေကိုပဲ clousure အနေဖြစ်သိမ်းထားပါတယ် ။
Scope chain မှာ လည်း variable b တန်ဖိုးက ၁၀ ဖြစ်နေပြီး outer() function execution ဖြစ်သွားတဲ့ နောက်မှာလည်း bကို 10 အဖြစ် closure တစ်ခုထဲမှာ ရှိပါတယ် ။ အဲ့ဒါကြောင့် JavaScript က a= 20 နဲ့ b = 10 လို့ သိပြီး a+b ကို calculate လုပ်ပေးပါတယ်။
အောက်ပါ code ကို ကူပြီး Chrome မှာ run ကြည့်ပါ။
inner function မှာ လည်း scope chains သုံးခုရှိပါတယ်။ ပထမဆုံး သူနဲ့ scope အတွင်းကဖြစ်တဲ့ variable a ကို access လုပ်ပါတယ် ။ နောက် outer() function ဖြစ်တဲ့ variable b ကိုလည်း access လုပ် ပါတယ်။ နောက်ပြီး သတ်မှတ်ထားတဲ့ defined လုပ်ထားတဲ့ global variables တွေကိုလည်း access လုပ်ပါတယ်။
function outer(){
var b = 10;
function inner(){
var a = 20;
console.log(`${a}+${b}`);
}
return inner;
}
var x = outer();
console.dir(x); //use console.dir() instead of console.log()
ပြီးရင် inspect ထောက်ကြည့်ပါ ။ Closure element ကို သေခြာတွေ့ပါလိမ့်မယ် ။ အဲ့ဒီမှာ b = 10 ဆိုပြီး closure က outer() function execution ဖြစ်ပြီး မူလအခြေအနေ ကို သိမ်းထားပါတယ် ။
inner function မှာ လည်း scope chains သုံးခုရှိပါတယ်။ ပထမဆုံး သူနဲ့ scope အတွင်းကဖြစ်တဲ့ variable a ကို access လုပ်ပါတယ် ။ နောက် outer() function ဖြစ်တဲ့ variable b ကိုလည်း access လုပ် ပါတယ်။ နောက်ပြီး သတ်မှတ်ထားတဲ့ defined လုပ်ထားတဲ့ global variables တွေကိုလည်း access လုပ်ပါတယ်။
Closure အလုပ်လုပ်ပုံ
function outer(){
var b = 10;
var c = 100;
function inner() {
var a = 20;
console.log(`a= ${a} b = ${b}`);
a++;
b++;
}
return inner();
}
var X = outer(); // outer() invoked the first time
var Y = outer(); // outer() invoked the second time
//end of outer() function executions
X(); // X() invoked the first time
X(); // X() invoked the second time
X(); // X() invoked the third time
Y(); // Y() invoked the first time
ဒီ code ကို run လိုက်ရင် output အနေနဲ့ ဒီလိုမြင်ရပါလိမ့်မယ်။
a=20 b=10
a=20 b=11
a=20 b=12
a=20 b=10
Closure အလုပ်လုပ်ပုံ ကို step by step ပြန်ကြည့်မည်ဆိုလျှင်
var X = outer(); // outer() invoked the first time
outer() function ကို ပထမအကြိမ် invoke လုပ်တဲ့အခါ
variable b ကို create လုပ်ပြီး value 10 ထားပါတယ်။
variable c ကို create လုပ်ပြီး value 100 ထားပါတယ်။
ဒါကို b(first_time) နဲ့ c(first_time) ဆိုပြီး ခနမှတ်ထားလိုက်ပါတယ်
inner function ကို return ပေးပြီး x ထဲမှာ assignချလိုက်ပါတယ်။ အဲ့ဒီအခါမှာ inner function ရဲ့ scope chain က b = 10 ကို closure အနေနဲ့ အသုံးပြုနေပါပြီ။
outer() function execution ဖြစ်သွားတဲ့အခါမှာ variable c က ပျောက်သွားပြီး variable b ကို closure အနေနဲ့ inner မှာ ကျန်ခဲ့ပါတယ် ။
var Y= outer(); // outer() invoked the second time
outer() function ကို ပထမအကြိမ် invoke လုပ်တဲ့အခါ
variable b ကို နောက်ထပ် အသစ် create လုပ်ပြီး value 10 ထားပါတယ်။
variable c ကို နောက်ထပ အသစ် create လုပ်ပြီး value 100 ထားပါတယ်။
ဒါကို b(second_time) နဲ့ c(second_time) ဆိုပြီး ခနမှတ်ထားလိုက်ပါတယ်။
inner function ကို return ပေးပြီး y ထဲမှာ assignချလိုက်ပါတယ်။ အဲ့ဒီအခါမှာ inner function ရဲ့ scope chain က b(second_time) = 10 ကို closure အနေနဲ့ အသုံးပြုနေပါပြီ။
outer() function execution ဖြစ်သွားတဲ့အခါမှာ variable c(second_time) က ပျောက်သွားပြီး variable b(second_time) ကို closure အနေနဲ့ inner မှာ ကျန်ခဲ့ပါတယ် ။
X(); // X() invoked the first time
X(); // X() invoked the second time
X(); // X() invoked the third time
Y(); // Y() invoked the first time
ဒီမှာဆိုရင် x() ကို ပထမအကြိမ် invoke လုပ်တဲ့အခါ
အရင်ဆုံး a ကို create လုပ်ပြီး value 20 ထားပါတယ်။
နောက်ပြီး a = 20 ပဲဖြစ်ပြီး b ကို closure value အဖြစ်ယူထားပါတယ်။
b(first_time)ဒါကြောင့် b=10 နဲ့ a =20
နောက်ပြီး a နဲ့ b ကို 1 စီတိုးပါမယ် ။
x() execution ဖြစ်သွားတဲ့အခါ a ကဒီတိုင်းကျန်ခဲ့ပြီး b(first_time) ကို closure အနေနဲ့ယူလို့ b(first_time) လည်း ကျန်ခဲ့ပါတယ်။ b = 10
x() ကို ဒုတိယအကြိမ် invoke လုပ်တဲ့အခါ
a ကို အသစ်ပြန် create လုပ်ပြီး value 20 ထားပါတယ်။
x() function ကို တစ်ခါ ထပ် declare လုပ်တိုင်း a ကိုအသစ်ပြန် create လုပ်ပါတယ်။
a ကတော့ 20 ပဲဖြစ်ပြီး b ကတော့ closure အနေနဲ့သိမ်းထားတာမို့ အပေါ်မှာ တစ်ပေါင်းထားတဲ့အတွက် 11 ဖြစ်သွားပါတယ် ။ b = 11
နောက်ပြီး a နဲ့ b ကို 1 စီထပ် တိုးပါမယ် ။
x() execution ဖြစ်သွားတဲ့အခါ a ကဒီတိုင်းကျန်ခဲ့ပြီး b(first_time) က closure အနေနဲ့ယူလို့ b(first_time) အနေနဲ့ပဲ ကျန်ခဲ့ပါတယ်။ b=11
x() ကို တတိယအကြိမ် invoke လုပ်တဲ့အခါ
a ကို အသစ်ပြန် create လုပ်ပြီး value 20 ထားပါတယ်။
x() function ကို တစ်ခါ ထပ် declare လုပ်တိုင်း a ကိုအသစ်ပြန် create လုပ်ပါတယ်။
a ကတော့ 20 ပဲဖြစ်ပြီး b ကတော့ closure အနေနဲ့သိမ်းထားတာမို့ အပေါ်မှာ တစ်ပေါင်းထားတဲ့အတွက် 12 ဖြစ်သွားပါတယ် ။ b =12
နောက်ပြီး a နဲ့ b ကို 1 စီထပ် တိုးပါမယ် ။
x() execution ဖြစ်သွားတဲ့အခါ a ကဒီတိုင်းကျန်ခဲ့ပြီး b(first_time) က closure အနေနဲ့ယူလို့ b(first_time) အနေနဲ့ပဲ ကျန်ခဲ့ပါတယ်။ b=12
ဒီမှာဆိုရင် Y() ကို ပထမအကြိမ် invoke လုပ်တဲ့အခါ
အရင်ဆုံး a ကို create လုပ်ပြီး value 20 ထားပါတယ်။
နောက်ပြီး a = 20 ပဲဖစ်ပြီး b ကို closure value အဖြစ်ယူထားပါတယ်။
b(second_time)b=10 နဲ့ a =20 ဖြစ်သွားပါတယ်။
နောက်ပြီး a နဲ့ b ကို 1 စီတိုးပါမယ် ။
x() execution ဖြစ်သွားတဲ့အခါ a ကဒီတိုင်းကျန်ခဲ့ပြီး b(second_time) ကို closure အနေနဲ့ယူလို့ b(second_time) လည်း ကျန်ခဲ့ပါတယ်။ b=10
Closures က JavaScript ရဲ့ subtle concepts ထဲက တစ်ခုဖြစ်တာကြောင့် ခက်ပေမဲ့ နားလည်လာတဲ့အခါ အရမ်းအသုံးဝင်ပါတယ် ။

No comments:
Post a Comment