Closures

Closure زمانی ایجاد می‌شود که یک تابع به متغیرهای بیرونی خودش دسترسی داشته باشد، حتی وقتی که آن تابع بعداً خارج از محیط اصلی اجرا شود.

🔹 به زبان ساده: تابع می‌تواند به داده‌های محیطی که ساخته شده دسترسی داشته باشد، حتی بعد از اتمام اجرای آن محیط.

1️⃣ مثال ساده

function outerFunction() { let count = 0; function innerFunction() { count++; console.log(count); } return innerFunction; } const counter = outerFunction(); counter(); // 1 counter(); // 2 counter(); // 3

🔹 innerFunction به متغیر count که داخل outerFunction تعریف شده دسترسی دارد.
🔹 حتی بعد از اینکه outerFunction اجرا شد، مقدار count حفظ می‌شود.

2️⃣ کاربردهای Closure

1️⃣ ایجاد داده‌های خصوصی (Private Variables)

function createCounter() { let count = 0; return { increment: function() { count++; }, getCount: function() { return count; } }; } const myCounter = createCounter(); myCounter.increment(); console.log(myCounter.getCount()); // 1

🔹 متغیر count فقط از طریق متدهای increment و getCount قابل دسترسی است.

2️⃣ Partial Application / Currying

function multiply(a) { return function(b) { return a * b; } } const double = multiply(2); console.log(double(5)); // 10

🔹 تابع داخلی به مقدار a دسترسی دارد حتی بعد از اجرای تابع خارجی.

3️⃣ Callbacks و Asynchronous

function delayedGreeting(name) { setTimeout(function() { console.log("Hello " + name); }, 1000); } delayedGreeting("Sara"); // بعد از 1 ثانیه: Hello Sara

🔹 تابع callback هنوز به پارامتر name دسترسی دارد چون یک closure ساخته شده.

3️⃣ نکات مهم

  • Closure حافظه مصرف می‌کند چون متغیرهای بیرونی حفظ می‌شوند.

  • بیشترین استفاده: حفظ state و ایجاد متغیرهای خصوصی

  • Arrow Function ها هم می‌توانند closure ایجاد کنند

📌 جمع‌بندی

  • Closure = تابع + دسترسی به محیط تعریفش

  • امکان حفظ state بعد از پایان اجرای تابع را فراهم می‌کند

  • کاربرد: متغیرهای خصوصی، callbackها، currying