Saturday, April 11, 2020

Closures in Action

closures in action
Document
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 ကြည့်ပါ။
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 ဖြစ်ပြီး မူလအခြေအနေ ကို သိမ်းထားပါတယ် ။
closures in action2
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