با عرض سلام خدمت کاربران محترم سایت پی وی لرن.
در این جلسه قصد داریم تا به آموزش Closure در جاوا اسکریپت JavaScript و توابع تو در تو در جاوا اسکریپت بپردازیم.
متغیر ها در جاوا اسکریپت از لحاظ قلمرو و محدوده به دو نوع محلی local و سراسری global تقسیم می شوند.
متغیر های سراسری می توانند با استفاده از closure ها تبدیل به متغیر های private شوند.
یک تابع می تواند علاوه بر متغیر هایی که داخل آن تعریف شده اند، به متغیر های خارج از بدنه خود نیز دسترسی پیدا کند.
مثال-۱ : دسترسی تابع به متغیرهای تعریف شده داخل بدنه تابع
1 2 3 4 | function myFunction() { var a = 4; return a * a; } |
مثال-۲ : دسترسی تابع به متغیرهای تعریف شده در خارج از بدنه ی تابع
1 2 3 4 | var a = 4; function myFunction() { return a * a; } |
در این مثال متغیر a یک متغیر سراسری می باشد.
در یک صفحه وب متغیر های سراسری به شی window تعلق دارند.
متغیر های سراسری می توانند توسط تمام اسکریپت صفحه استفاده و تغییر داده شوند.
اما متغیر های محلی فقط در داخل بلوکی که تعریف شده اند قابل دسترس هستند و توابع دیگر نمی توانند از آن ها استفاده کنند.
نکنه: اگر متغیری بدون کلمه کلیدی var ایجاد شود، همیشه سراسری است حتی با وجود اینکه در داخل یک تابع ایجاد شده باشد.
متغیر های سراسری تا هنگامی که برنامه شما (پنجره یا صفحه وب) تمام نشده باشد، به اصطلاح زنده و قابل استفاده هستند.
اما متغیر های محلی عمر کوتاهی دارند و با پایان اجرای تابع و بلوکی که در آن ایجاد شده اند، تمام می شوند.
فرض کنید شما می خواهید از یک متغیر برای شمارش چیزی استفاده کنید و شما می خواهید این شمارنده برای تمام توابع موجود باشد.
شما می توانید از یک متغیر عمومی و یک تابع برای افزایش شمارنده استفاده کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // Initiate counter var counter = 0; // Function to increment counter function add() { counter += 1; } // Call add() 3 times add(); add(); add(); // The counter should now be 3 |
یک مشکل در راه حل بالا وجود دارد: هر کدی از صفحه می تواند بدون فراخوانی ()add شمارنده را تغییر دهد.
برای جلوگیری از تغییر کدهای دیگر، باید از تابع ()add استفاده کرد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // Initiate counter var counter = 0; // Function to increment counter function add() { var counter = 0; counter += 1; } // Call add() 3 times add(); add(); add(); //The counter should now be 3. But it is 0 |
کد فوق نتیجه نمی دهد، زیرا شمارنده ی عمومی را به جای شمارنده ی محلی نمایش دادیم.
ما می توانیم شمارنده عمومی را حذف کنیم و با تابع return می توانیم به شمارنده محلی دسترسی یابیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Function to increment counter function add() { var counter = 0; counter += 1; return counter; } // Call add() 3 times add(); add(); add(); //The counter should now be 3. But it is 1. |
همانطور که گفتیم تمام توابع به متغیر های سراسری دسترسی دارند.
در واقع تمام توابع به بلوک بالای خودشان دسترسی دارند.
در مثال زیر یک تابع داخلی به نام ()plus به متغیر counter در تابع والد خود دسترسی دارد:
1 2 3 4 5 6 | function add() { var counter = 0; function plus() {counter += 1;} plus(); return counter; } |
به مثال زیر توجه کنید:
1 2 3 4 5 6 7 8 9 10 | var add = (function () { var counter = 0; return function () {counter += 1; return counter} })(); add(); add(); add(); // the counter is now 3 |
توضیحات:
متغیر add به مقدار برگشتی یک تابع فراخوان اختصاص داده شده است.
تابع خود فراخوان تنها یک بار ایجاد می شود. این تابع مقدار counter را به ۰ تغییر داده و یک تابع داخلی را برگشت می دهد.
از این طریق add یک تابع محسسوب می شود.
بخش جالب ماجرا اینجاست که add می تواند به شمارنده بلوک والد خود دسترسی داشته باشد.
این کار Closure نامیده می شود که به توابع این امکان را می دهد تا متغیر های private داشته باشند.
counter توسط بلوک تابع ناشناس محافظت می شود و فقط می تواند توسط تابع add تغییر کند.
یک Closure تابعی است که به اجزای بلوک والد خود دسترسی دارد حتی اگر تابع بسته شده باشد.
جلسه آموزش Closure در جاوا اسکریپت JavaScript نیز به پایان رسید.
ziaarabshahi.shayan
متاسفانه اصلا قابل فهم نیست. نمیدونم من هم از w3schools خوندم هم از چند سایت فارسی. نمیدونم چرا هیچکس خوب توضیح نداده.
صادق
ببینید تمام ویژگی های یک زبان برنامه نویسی به یک اندازه کاربرد ندارند. کلاژور ها هم در مواقع خیلی خاص به کار میان. هدف این ویژگی اینه که بتونیم برای یک تابع متغیر هایی رو در ابتدای تعریف ایجاد کنیم و بدون مقدار دهی اولیه مجدد در هربار فراخوانی اون تابع، مقدار متغیر هاش رو تغییر بدیم. یه جورایی هر تابع حافظه خودش رو برای متغیر هاش داره. این لینک توضیحات خوبی داده
شایان
سلام. ممنون از پاسخگوییتون. باورم نمیشه ۲ سال گذشته. لطفا این کامنت منو پاک کنید. اسممو تو گوگل سرچ میکنم ان میاد خخخ.