شعبده بازی با جاوااسکریپت !

جاوا اسکریپت عملا امروز داره بر دنیای وبِ مدرن سلطنت می کنه و این امر به دلیل ماهیت پویا، همچنین یادگیری راحت اون هست !

گفتم راحتی در یادگیری اما در عین این راحتی جاوا اسکریپت پر از سردرگمی هایی هست که جواب اونها رو حتی در Stackoverflow هم نمی تونید پیدا کنید :دی

در واقع موضوع پست ما همینه، می خوام شما رو با چند خط کد ساده به چالش بکشم تا خودتون رو یکم محک بزنید.



مفهومی وجود داره به نام Closure اگه اشتباه نکنم (ما تجربیآ تو قید و بند اصلاحا نیستیم D: )

خب شما حتما می دونید متغیر محلی چیه، گلوبال چی هست !

می خوام با دونسته هاتون جواب این سوال رو بدید،

خروجیه کد زیر چیه ؟

function outside() {
var text = "I love JavaScript."
	function inside() {
		console.log(text);
	}
	inside();
};
outside();                  

اگه با جاوا اسکریپت آشنایی داشته باشین، حتما جواب رو درست گفتین

خروجی کد بالا هست:

// "I love JavaScript"

حالا یک کد ساده ی دیگه :

function outside() {
        var text = "I love JavaScript."
        return function() {
                console.log(text);
        };
 };
 outside()();

درسته!
کد بالا هم مثل مثال قبل :

// "I love JavaScript."

رو چاپ می کنه :)

پس ما اگه تابع بالا رو مثل مثال پایین در یک متغیر بریزیم، باز هم خروجی مثل دفعات قبل خواهد بود، مثال:

function outside() {
    var text = "I love JavaScript."
    return function() {
        console.log(text);
    };
};
var trueOutside = outside();
trueOutside(); // "I love JavaScript."

کد بالا تابع outside رو داخل متغیر trueOutside میریزه و چون تابع outside یک تابع رو بازگشت میده، در صورتی که شما trueOutside رو با () درج کنید، تابع بازگشت داده شده صدا زده میشه !

و اما چالش
در کد زیر، در هر بار صدا زدن تابع trueOutside چه چیزی در خروجی چاپ خواهد شد ؟

function outside() {
    var text = 1;
    return function() {
        text++;
        console.log(text);
    };
};
var trueOutside = outside();
trueOutside(); // ؟
trueOutside(); // ؟
trueOutside(); // ؟

جواب رو خودم میگم اما قبل از خوندن جواب، خودتون به جواب فکر کنید بعد پاسخش رو در خط بعد بخونید:
.
.
کد بالا اول تابع رو در متغیر میریزه، پس تمامی متغیر های داخل تابع هم در متغیر ذخیره میشن،
با هربار صدا زدن تابع بازگشت داده شده توسط تابع پدر، متغیر ذخیره شده از تابع پدر فراخوانی میشه و در عملیات تابع بازگشت داده شده شرکت داده میشه
پس خروجی از کد بالا میشه :

var trueOutside = outside();
trueOutside(); // 2
trueOutside(); // 3
trueOutside(); // 4

حالا یک تست هوش:
در مثال بالا trueOutside رو سه بار صدا زدیم و هربار یک رقم به text اضافه شد
حالا اگر ۳ بار تابع outside رو به صورت زیر صدا بزنیم چه اتفاقی رخ خواهد داد ؟

outside()(); // ؟
outside()(); // ؟
outside()(); // ؟

قبل از خوندن جواب خودتون روش فکر کنید
جواب:
.
.
.
در هر سه بار عدد ۲ چاپ میشه، خودتون به علتش فکر کنید

تا اینجا با ی سری از قواعد جاوا اسکریپت آشنا شدید

پس با دونسته هاتون بریم سراغ یه شعبده بازیه جالب

خروجی در کد زیر چیست ؟
اخطار:عجولانه پاسخ ندهیــــد !

var funcs = [];
for (var i = 0; i < 3; i++) { // سه تا تابع میسازه
    funcs[i] = function() { // هر سه تا رو ذیره می کنه در آرایه
        console.log("My value: " + i); // هر سه تابع باید این خروجی رو چاپ کنن
    };
}
for (var j = 0; j < 3; j++) {
    funcs[j](); // در اینجا توابع ساخته شده در بالا رو دونه دونه صدا میزنیم
}

آفریــــــــــــــن
حتما شما هم به جواب رسیدین:

My value: 0
My value: 1
My value: 2

ضمن تبریک به مناسبت پاسخ اشتباهتون (اگر جوابتون با این بالایی برابر بود) باید خدمتتون عرض کنم خروجی کد بالا هست:

My value: 3
My value: 3
My value: 3

نتیجه مشاهدات خود را یادداشت کرده و با دوستان خود به اشتراک بگذارید ;)
تا شعبده بازی دیگر، درود و صد بدرود.

@mohammaditor

#یا_علی