به نام خدا با عرض سلام و احترام خدمت شما دوستان عزیز. در ادامه آموزش جاوا اسکریت این جلسه قصد داریم به مبحث Closures در جاوا اسکریپت بپردازیم.با ما همراه باشید.
اشنایی با Closures (کلوژرها)
در جلسه توابع در جاوا اسکریپت آموخته اید که در جاوا اسکریپت دامنه یک متغیر می تواند سراسری یا محلی باشد. در ES6 میتوانید با استفاده از کلمه کلیدی let
متغیرهایی با محدوده بلوکی ایجاد نمایید.
یک متغیر سراسری را می توان در هر جایی از برنامه استفاده و دستکاری کرد، در حالی که یک متغیر محلی فقط در تابعی که در آن تعریف شده قابل دسترسی و دستکاری است.
با این حال، موقعیتهای خاصی وجود دارد که میخواهید یک متغیر در سراسر اسکریپت در دسترس باشد،اما شما نمی خواهید که هر بخشی از کد شما به طور تصادفی مقدار آن را تغییر دهد.
بیایید ببینیم اگر سعی کنید با استفاده از متغیر سراسری به این هدف برسید چه اتفاقی می افتد:
// Global variable var counter = 0; // A function dedicated to manipulate the 'counter' variable function makeCounter() { return counter += 1; } // Calling the function makeCounter(); console.log(counter); // Prints: 1 makeCounter(); console.log(counter); // Prints: 2 // Trying to manipulate the 'counter' variable from outside counter = 10; console.log(counter); // Prints: 10
همانطور که در مثال بالا مشاهده می کنید، مقدار متغیر counter
را می توان از هر نقطه ای از برنامه، بدون فراخوانی تابع ()makeCounter
(خط 17) تغییر داد.
حالا بیایید سعی کنیم با متغیر محلی به همان چیزی برسیم و ببینیم چه اتفاقی میافتد:
function makeCounter() { // Local variable var counter = 0; // Manipulating the 'counter' variable return counter += 1; } // Calling the function console.log(makeCounter()); // Prints: 1 console.log(makeCounter()); // Prints: 1
در این حالت متغیر counter
را نمی توان از خارج دستکاری کرد، زیرا ان برای تابع()
makeCounter
محلی میباشد.اما مقدار آن نیز پس از فراخوانی تابع بعدی افزایش نمی یابد،زیرا هر بار که تابع را فراخوانی می کنیم، مقدار متغیر counter
را بازنشانی می کند، که در مثال بالا به وضوح می توانید آن را مشاهده نمایید(خط شماره 11).کلوژ در جاوا اسکریپت می تواند مشکل ما را حل کند.
Closures اساساً یک تابع درونی است که حتی پس از اتمام اجرای تابع والد به محدوده تابع والد دسترسی دارد.این کار با ایجاد یک تابع در یک تابع دیگر انجام می شود.
به مثال زیر نگاهی بیندازید تا ببینید چگونه کار می کند:
function makeCounter() { var counter = 0; // Nested function function make() { counter += 1; return counter; } return make; } /* Execute the makeCounter() function and store the returned value in the myCounter variable */ var myCounter = makeCounter(); console.log(myCounter()); // Prints: 1 console.log(myCounter()); // Prints: 2
()
make از تابع خارجی ()
makeCounter برگردانده می شود.بنابراین مقدار myCounter
تابع ()
make داخلی است (خط شماره 14) و فراخوانی myCounter
به طور موثر ()
make را فراخوانی می کند.در جاوا اسکریپت، توابع را می توان به متغیرها اختصاص داد، به عنوان آرگومان به توابع دیگر ارسال کرد، می تواند در توابع دیگر تودرتو باشد و ….()
make همچنان قادر به دسترسی به مقدار متغیر counter
تعریف شده در تابع خارجی است، حتی اگر تابع ()
makeCounter قبلاً اجرای خود را به پایان رسانده باشد (خط شماره 14). این اتفاق می افتد زیرا توابع در جاوا اسکریپت به صورت کلوژر میباشد.()
make یک کلوژر است که کد آن به شمارنده متغیر خارجی اشاره دارد.این بدان معناست که هر زمان که تابع ()
make فراخوانی میشود، کد داخل آن میتواند به متغیر counter
دسترسی داشته باشد و بهروزرسانی شود، زیرا در Closure ذخیره میشود.در نهایت، از آنجایی که اجرای تابع خارجی به پایان رسیده است، هیچ بخش دیگری از کد نمی تواند به متغیر شمارنده دسترسی داشته یا دستکاری کند.فقط تابع داخلی به آن دسترسی انحصاری دارد.
مثال قبلی را می توان با استفاده از عبارت تابع ناشناس نیز نوشت:
// Anonymous function expression var myCounter = (function() { var counter = 0; // Nested anonymous function return function() { counter += 1; return counter; } })(); console.log(myCounter()); // Prints: 1 console.log(myCounter()); // Prints: 2
نکته: در جاوا اسکریپت، همه توابع به دامنه سراسری و همچنین محدوده بالای آنها دسترسی دارند.از آنجایی که جاوا اسکریپت از توابع تو در تو پشتیبانی می کند.این معمولاً به این معنی است. که توابع تودرتو به هر مقداری که در یک محدوده بالاتر از جمله محدوده تابع والد آن اعلام شده است دسترسی دارند.
دیدگاهتان را بنویسید