Closureها (Function Closures)
«Closure در جاوااسکریپت» یعنی تابع به متغیرهای اطرافش دسترسی دارد. حتی بعد از پایان اجرای تابع والد. مثل وقتی کلید کمد را فقط خودت نگه می داری.
متغیرهای محلی و عمومی
متغیر محلی (Local Variable) فقط داخل تابع دیده می شود. اما متغیر عمومی (Global Variable) همه جا دیده می شود.
مثال: محلی
function myFunction() {
let a = 4;
return a * a;
}
مثال: عمومی
let a = 4;
function myFunction() {
return a * a;
}
هشدار: متغیر بدون let/const/var «اعلام نشده» است و عمومی می شود.
function myFunction() {
a = 4;
}
دردسر شمارنده عمومی
می خواهیم شمارنده داشته باشیم. ولی هر کدی می تواند آن را تغییر دهد.
let counter = 0;
function add() {
counter += 1;
}
add();
add();
add();
نکته: اگر داخل تابع دوباره counter بسازیم، هر بار صفر می شود.
function add() {
let counter = 0;
counter += 1;
}
add();
add();
add();
بازگرداندن مقدار هم کافی نیست. چون هر بار دوباره صفر می شود.
function add() {
let counter = 0;
counter += 1;
return counter;
}
let x = 0;
x = add();
x = add();
x = add();
توابع تو در تو و مسیر راه حل
تابع داخلی به متغیرهای تابع والد دسترسی دارد. این دسترسی پایه closure است.
function add() {
let counter = 0;
function plus() {
counter += 1;
}
plus();
return counter;
}
Closure: شمارنده خصوصی و امن
با closure متغیر خصوصی می سازیم. یعنی فقط از راه تابع داخلی تغییر می کند.
function myCounter() {
let counter = 0;
return function () {
counter += 1;
return counter;
};
}
const add = myCounter();
add();
add();
add();
نکته: تابع داخلی به counter دسترسی دارد. حتی پس از تمام شدن myCounter.
گام های تمرینی
- یک تابع سازنده شمارنده بنویس.
- داخلش counter بساز و صفر کن.
- تابع داخلی برگردان که counter را یکی افزایش دهد.
برای مرور closure در جاوااسکریپت همین صفحه را نشانه گذاری کن. همچنین بخش های مرتبط: bind و call.
جمع بندی سریع
- closure یعنی دسترسی پایدار به محدوده والد.
- با آن متغیر خصوصی می سازیم.
- حالت را بین فراخوانی ها نگه می داریم.
- از دست کاری عمومی جلوگیری می کنیم.