متغيرهاي جاوااسكريپت مي توانند به محدوه محلي يا جهاني تعلق داشته باشند.
متغيرهاي جهاني را ميتوان با بسته شدن(closures) محلي كرد.
يكfunction ميتواند به تمام متغيرهائيكه در داخل تعريف شده اند دسترسي پيدا كند مشابه زير:
مثال ـ متغير هاي داخلي تابع مثلa
function myFunction() { let a = 4; return a * a; }
همچنين يك تابع ميتواند به متغير هاي كه مشابه زير در خارج تابع تعريف ميشوند دسترسي داشته باشد.
مثال ـ تعريف متغير خارج تابع ودسترسي تابع به آن
let a = 4; function myFunction() { return a * a; }
در مثال فوق متغيرa يك متغير جهاني يا سراسريست. در صفحات وب متغيير جهاني متعلق به صفحه ميباشد.
متغير هاي سراسري ميتوانند مورد استفاده ساير اسكريپت هاي صفحه باشند.
در مثال اول متغيرa يك متغير محلي است . يك متغير محلي فقط ميتواند در داخل تابعي كه تعريف شده استفاده گردد .از تابع ديگر وساير كد هاي برنامه پنهان است.
متغير هاي محلي وسراسري همنام ، متغيرهاي مختلفي هستند .اگر يكي ارآنها اصلاح شود، روي همنام آن تاثيري ندارد.
توجه ـ متغير هاي ايجاد شده بدون يك كيورد تعريفي(var, let, const) هميشه سراسري هستند حتي اگر در داخل تابع ايجاد شده باشد.
مثال ـ متغيرa كه در تابع ايجاد شده سراسريست .
function myFunction() {
a = 4;
}
متغيرهاي جهاني تازماني كه صفحه ناديده گرفته شود فعال هستند، مانند زماني كه به صفحه ديگري پيمايش(navigate ) ميكنيد، يا پنجره ويندو را مي بنديد .
متغيرهاي محلي طول عمر كمتري دارند، آنها هنگام فراخواني تابع ايجاد و در پايان اجراي تابع حذف ميشوند.
فرض كنيد ميخواهيد از يك متغيربراي شمارش موردي استفاده نمائيد .و لازم است اين شمارنده براي همه توابع در دسترس باشد .فرض براين باشد كه شمارش در توابع يا يك تابع انجام شود .براي اين متغير سراسري بايد تعريف و درتوابع استفاده گردد.
مثال ـ تدوين شمارنده در تابع
// Initiate counter
let counter = 0;
// Function to increment counter
function add() {
counter += 1;
}
// Call add() 3 times
add();
add();
add();
در مورد روش فوق مشكلي وجود دارد، هر كدي در داخل صفحه ميتواند مقدار شمارنده را بدون فراخوانيadd() تغيير دهد .
به نظر مي آيد كه بايد شمارنده براي تابعadd() محلي باشد، تا از تغيير ديگران بدور باشد .مشابه مثال زير:
مثال ـ شماره با متغيرمحلي
// Initiate counter
let counter = 0;
// Function to increment counter
function add() {
let counter = 0;
counter += 1;
}
// Call add() 3 times
add();
add();
add();
//The counter should now be 3. But it is 0
متوجه شده ايد كه مثال فوق كار نميكند، زيرا شمارنده جهاني بجاي شمارنده محلي نمايش داده ميشود.
ميتوان شماره سراسري را حذف وبه تابع اجازه داده شود كه شمارنده محلي برگشت دهد .مطابق مثال زير
مثال ـ برگشت شمارنده توسط تابع
// Function to increment counter function add() { let counter = 0; counter += 1; return counter; } // Call add() 3 times add(); add(); add(); //The counter should now be 3. But it is 1.
اين هم نتيجه مورد نظر را ندارد ، زيرا هربار كه تابع فراخوان ميشود شمارنده به حالت اوليه برميگردد، يا اصطلاحاrest ميشود .
يك تابع تودر توي جاوااسكريپت ميتواند اين مشكل را برطرف نمايد.
همه توابع جاوااسكريپت به متغيرهاي سراسري دسترسي دارند .در حقيقت، در جاوااسكريپت توابع به متغير ميدان بالائي خود ميتوانند دسترسي داشته باشند.
جاوااسكريپت توابع تودرتو را پشتيباني ميكند .تابع داخل تابع ديگر به متغير تابع والد آن دسترسي دارد.
مثال ـ دراين مثال تابع داخليplus() به متغير شمارنده در تابع والد دسترسي دارد .
function add() { let counter = 0; function plus() {counter += 1;} plus(); return counter; }
اگر ميتوانستيم از بيرون به تابعplus() دسترسي پيدا كنيم، مشكل شمارنده را حل ميكرد.
همچنين لازم است كه راهي پيدا شودتا اجرايcounter=0 يك مرتبه انجام شود .براي اين كارclosure لازم است .
بياد آوريد توابع خودفراخوان را، اين ها چه كاري انجام ميدهند.
مثال ـ تابع خود فراخوان براي حل شمارنده
const add = (function () { let counter = 0; return function () {counter += 1; return counter} })(); add(); add(); add(); // the counter is now 3
تابع در حالت خودفراخواني خود كه فقط يك بار است، بازگشتي خود را در متغيرadd قرار ميدهد .ودر اين اجرا متغيرcounter=0 ميشود ومحتوي متغيرadd تابع داخلي است.
تابع در متغيرadd فقط شمارنده را اضافه مي نمايد، وبراي آن متغير شمارنده سراسري است اما براي تابع والد محلي است .نميتوان آنرا در خارج والد تغيير داد.
به اين ترتيبadd تبديل بيك تابع ميشود .بخش شگفت انگيز اينست كه ميتواند به شمارنده درمحدوده والد دسترسي پيداد كند.
اين كار بسته شدن جاوااسكريپت ناميده ميشود .اين امكان را براي تابع فراهم ميكندكه تابع تابع داراي متغير خصوصي بارث برده باشد.
شمارنده در ميدان تابع ناشناس محافظت ميشود وتنها با تابعadd() ميتوان مقدار آنرا تغيير داد
توابع تودر توي خودفراخوان، اولي تابع والد كه در متن خود تابع اولادي دارد .در خود فراخواني تابع والد، تابع اولاد را برگشت ميدهد وخود بسته يا غير فعال شده و تابع اولاد با ارثيه يعني متغيرهاي والد آماده فراخواني است.
يك بسته كننده تابعي است كه داراي دسترسي بميدان والد دارد، حتي بعداز بسته تابع والد.