درک آسان Closure در جاوااسکریپت

درک آسان Closure در جاوااسکریپت
closure به برنامه نویس جاوااسکریپت این امکان رو میده که سریع‌تر، خلاقانه‌تر و کاربردی‌تر کدنویسی انجام بده. ما به طور مداوم در برنامه نویسی جاوااسکریپت با این مفهوم روبرو خواهیم بود، اصلا مهم نیست که شما قبلا به صورت حرفه ای برنامه نویسی کار کردید یا خیر ولی اگر قصد دارید وارد این زبان برنامه نویسی شوید حتما با این موضوع روبرو خواهید بود.مفهوم Closure در واقع شاید پیچیده‌تر از بحث حوزه تعریف متغیر باشه ولی بعد از مطالعه این مطلب به آسانی میتونید این موضوع رو درک کنید. در واقع Closure بسیار جذاب و یکی از کاربردی‌ترین بخش ها برای برنامه نویسان جاوااسکریپت هست. پس بیایید باهم بیشتر در موردش بدونیم smiley
دارالترجمه رسمی
دارالترجمه رسمی پارسیس شامل خدمات ترجمه رسمی و تخصصی در بیش از 60 زبان زنده دنیا
جای بروشور دیواری
خرید جای بروشور دیواری و رومیزی
افزونه های سئو وردپرس
بهترین افزونه های سئو وردپرس به صورت کاملا فارسی
تعمیر لوازم خانگی
تعمیر جاروبرقی، مایکروفر، بخارشوی، ظرفشویی، لباسشویی، سولاردام، کولرگازی
خودتان را اینجا معرفی کنید

قبل از ادامه‌ی موضوع بهتون توصیه می‌کنم حتما مطلب قبلی که در رابطه با "حوزه تعریف متغیرها در جاوااسکریپت" بود رو کامل مطالعه و درک کنید چونکه یادگیری مفهوم Closure نیازمند درک کامل این مبحث هست.

در مباحث قبلی اگر یادتون باشه دو نوع متغیر به صورت local  و global  داشتیم که نحوه دسترسی اونها رو مشخص می‌کرد.
به طور کلی میشه گفت نوع دیگری متغیر به نام private  داریم که درclosure  ها ساخته میشن!
 

Closure  چیست؟!

Closure  یک تابع هست که به متغیرهای توابع خارجی دسترسی دارد!
Closure سه سطح دسترسی داره :
1 – دسترسی به حوزه یا محدوده خودش
2 – دسترسی به متغیرهای توابع خارجی
3 – دسترسی به متغیرهای global
 
با بررسی مثال ساده زیر تا حدودی میشه متوجه موضوع شد :
function showName (firstName, lastName) {
​var nameIntro = "Your name is ";
// این تابع داخلی به متغیرهای تابع خارجی خودش دسترسی داره
​function makeFullName () {
  ​return nameIntro + firstName + lastName;
}
​
​return makeFullName ();
}
​
showName ("Majid", "Online"); // Your name is MajidOnli
Closureها به صورت خیلی کاربردی در Node.js استفاده می‌شوند و به طور کلی در هر کتابخانه ی جاوااسکریپت استفاده های زیادی از میشه، با بررسی مثال زیر میبینیم که در jQuery هم کاربردهای خوبی می‌تونه داشته باشه : یک مثال ساده در jQuery :

$(function() {
​
​var selections = [];
$(".niners").click(function() { // this closure has access to the selections variable​
     selections.push (this.prop("name")); // آپدیت مقدار متغیر بیرونی
  });
​
});

Closureها دسترسی به متغیرهای توابع بیرونی دارند حتی بعد از return کردن تابع!

یکی از مهمترین و حساس‌ترین بخش های Closure  این مبحث هست که Closure  به متغیرهای توابع خارجی دسترسی داره حتی بعد از return شدن اون تابع! بله درست متوجه شدید حتی بعد از return  شدن. اگر بخواهیم بهتر توضیح بدیم به این معناست که وقتی شما تابعی رو تعریف میکنید و در قسمتی از برنامه اون تابع رو فراخوانی میکنید و تابع return میشه، حتی بعد از return  شدن تابع خارجی، شما بازهم میتونید به تابع داخلی دسترسی داشته باشید. با بررسی دو مثال زیر به خوبی این موضوع رو میتونید بفهمید :
 

function celebrityName(firstName) {
var nameIntro = "This celebrity is ";
    // this inner function has access to the outer function's variables, including the parameter​
    function lastName(theLastName) {
       return nameIntro + firstName + theLastName;
    }
return lastName;
}
​
​var mjName = celebrityName("Majid"); // در این قسمت تابع خارجی صدا زده میشه
​
​// The closure (lastName) is called here after the outer function has returned above​
​// the closure still has access to the outer function's variables and parameter​
mjName("Online"); // This celebrity is MajidOnline

مثال بعدی :

function makeAdder(x) {
   return function(y) { 
       return x + y; }; 
   }; 

var add5 = makeAdder(5); 
var add10 = makeAdder(10); 

console.log(add5(2)); // 7 
console.log(add10(2)); // 12

فکر کنم دو تا مثال فوق موضوع رو کامل تفهیم کرده و نیازی به توضیح بیشتر این موضوع نیست. smiley
اگر احیانا در مورد نحوه صدا زدن تابع در دو مثال بالا مشکل دارید و متوجه نشدید بهتون توصیه میکنم قبل از ادامه مبحث این مطلب رو مطالع نمائید : " توابع و روش های فراخوانی آن ها در جاوااسکریپت "
 

Closureها مقدار بازگشتی را در متغیر اصلی تابع خارجی ذخیره می‌کنند.

یکی از نکات جذاب Closureها هنگامی هست وقتی متغییری مقدارش تغییر داده میشه، قبل از ارسال مقدار صدا زده شده مقدار جدید رو ریپلیس میکنه، این ویژگی قدرتمند یکی از راههای خلاقانه ست برای اینکه برنامه ای که می‌نویسیم تحت کنترل داشته باشیم. مثل متغیرهای private که در مثال اول ارائه کردیم.
مثال دیگری رو برای تفهیم موضوع بررسی کنیم :
function celebrityID () {
var celebrityID = 999; 

// All the inner functions have access to the outer function's variables​
   return {
      getID: function () {
          // این قسمت آخرین مقدار متغیر رو بازمیگردونه
          // در این قسمت آخرین مقدار متغیر پاس داده میشه حتی بعد از تغییر مقدار آخرین مقدار بازگردانده میشه
          return celebrityID;
      },
      setID: function (theNewID) {
         // این قسمت مقدار متغیر تابع خارجی را تغییر میده در هر زمانی که تغییری ایجاد بشه
         celebrityID = theNewID;
      }
   }
}
​
​var mjID = celebrityID (); // در این قسمت تابع خارجی صدا زده میشه
mjID.getID();     // 999​
mjID.setID(567); // مقدار متغیر خارجی تغییر داده میشه
mjID.getID();    // 567: آخرین مقدار متغیر تابع خارجی پاس داده میشه
 enlightenedبا توجه به اینکه مقدار متغیر تابع خارجی در Closureها آپدیت میشه و بعد از تغییر آخرین مقدار بازگردانده میشه هنگامی که در حلقه‌ها از این توابع استفاده کردیم باید مواظب استفاده درست Closureها باشیم و بیشتر دقت کنیم.
امیدوارم مفید بوده باشه و تونسته باشم مفهوم رو به طور کامل برسونم.
شاد و موفق باشید wink

من میکائیل اندیشه هستم که از سال ۲۰۱۱ وارد حوزه برنامه نویسی و طراحی وب شدم، ابتدا با زبان‌ c++ در رشته تحصیلیم ( مهندسی فناوری اطلاعات ) آشنا شدم و پس از آن وارد طراحی وب سمت کلاینت ( Front-End ) شدم و پس از چند سال کار و تجربه در این حوزه از اواسط ۲۰۱۷ وارد برنامه نویسی و سمت بک اند شدم و با زبان php کار میکنم. به زبان‌های php و javascript علاقه زیادی دارم و سعی میکنم در این دو بخش بیشتر یاد بگیرم.

نظرات و سوالات کاربران

ارسال پاسخ sara
sara
چهارشنبه ۲۸ آذر ۱۳۹۷ ۱۳:۲۹
عالی بود مرسی
ارسال پاسخ نیلوفر
نیلوفر
سه شنبه ۳۰ مرداد ۱۳۹۷ ۱۸:۵۷
خیلی عالی توضیح دادین با اینک من مفهوم closure رو برای پایتون میخواستم یاد بگیرم و اصلا JS بلد نیستم ولی توضیحاتتون خیلی شفاف بودن. خیلی ممنون :)
ارسال پاسخ زهرا
زهرا
سه شنبه ۱۹ اردیبهشت ۱۳۹۶ ۰۸:۳۳
ببخشید واسم جا نیوفتاد
کاش با فیلم می بود
ارسال پاسخ myfirst
myfirst
دوشنبه ۲۰ دی ۱۳۹۵ ۲۲:۳۱
سلام. تو مثال اولتون باید اینجوری فراخوانی کنید:
showName ("Majid", "Online")();
ارسال پاسخ میکائیل
میکائیل
شنبه ۲۶ دی ۱۳۹۴ ۱۲:۰۲
در پاسخ به دیدگاه محمد نبی زاده ارسال شده در شنبه ۱۹ دی ۱۳۹۴ ۱۲:۱۰

عالی

خوشحالم مورد پسندتون بوده :)
ارسال پاسخ محمد نبی زاده
محمد نبی زاده
شنبه ۱۹ دی ۱۳۹۴ ۱۲:۱۰

عالی