در جاوااسکریپت به طور کلی توابعی هستند که به scope تابع خارجی خود حتی بعد از به پایان رسیدن آن دسترسی دارند. این جمله به این معناست یک closure به تمامی متغیرها و آرگومان های تابع خارجی خود دسترسی دارد.
هر تابع در جاوااسکریپت یک closure است.
برای این که به مفهوم closureها بهتر پی ببریم ابتدا Lexical Scope را بررسی میکنیم . این مفهوم در جاوااسکریپت اشاره به قابلیت دسترسی به متغیرها و توابع و اشیاء براساس موقعیت آن ها در کد دارد.
برای درک بهتر به مثال زیر توجه کنید :
در سورس کد بالا تابع inner میتواند به داده های outerFunction یعنی متغیر outer Variable و هم به داده های global scpe یعنی متغیر globalVariable دسترسی داشته باشد.
همچنین تابع outerFunction به داده های اسکوپ خود و global scope میتواند دسترسی داشته باشد.
در واقع در مثال بالا تابع innerfunction توسط lexical scope مربوط به outerfunction و global scope احاطه شده است و به همین دلیل به داده های آن ها دسترسی دارد.
برای فهم بیشتر بهتر است یک سری مثال را بررسی کنیم :
همانطور که مشاهده میشود ابتدا تابع makeCounter صدا زده شده و یک تابع به نام getCurrentرا بازمیگرداند و در متغیر hitsذخیره میشود. با هربار صدا زدن تابع hits مقدار count به حالت اولیه باز نمیگردد و مقدار قبلی خود را حفظ میکند.
این اتفاق به این دلیل است که با هر صدا زدن تابع hits، اسکوپ جدید و مخصوص به آن تابع ایجاد میشود اما تنها یک اسکوپ برای تابع makeCounter ایجاد می شود و به این دلیل که متغیر count داخل اسکوپ تابع makeCounter تعریف شده است با هر صدا زدن تابع hits مقدارش افزایش پیدا میکند و دوباره از صفر آغاز نمیشود.
در قسمت بعدی این مقاله در این موضوع که closure چگونه کار میکند با جزئیات بیشتر بحث میکنیم.
منابع :
1- https://blog.bitsrc.io/a-beginners-guide-to-closures-in-javascript-97d372284dda
2- You Don't know JS by ( Kyle Simpson )