Closure و this در جاوااسکریپت – حافظهٔ دامنه و زمینهٔ اجرایی در توابع

Closure و this دو مفهوم بنیادی و گاه گیج‌کننده در جاوااسکریپت هستند. این مقاله به تعریف دقیق closure به‌عنوان حافظهٔ متغیرهای بیرونی در توابع، و بررسی رفتار پویا و وابسته به نحوهٔ فراخوانی در this می‌پردازد. با مثال‌های عملی، تفاوت بین دامنهٔ ثابت و زمینهٔ اجرایی پویا روشن می‌شود.

closurethisexecution-contextscope

~3 دقیقه مطالعه · آخرین به‌روزرسانی ۲۸ مهر ۱۴۰۴

Closure چیست؟


Closure زمانی رخ می‌دهد که یک تابع، متغیرهایی از دامنهٔ بیرونی خود را به خاطر می‌سپارد و حتی در زمانی که در دامنه‌ای دیگر اجرا می‌شود، همچنان به آن‌ها دسترسی دارد.


فقط توابع دارای closure هستند — نه اشیاء. برای مشاهدهٔ closure، باید تابع را در دامنه‌ای متفاوت از محل تعریفش اجرا کنیم.


مثال:


function greeting(msg) {
  return function who(name) {
    console.log(`${msg}, ${name}!`);
  };
}
var hello = greeting("Hello");
var howdy = greeting("Howdy");

hello("Kyle");  // Hello, Kyle!
hello("Sarah"); // Hello, Sarah!
howdy("Grant"); // Howdy, Grant!

تابع داخلی who به متغیر msg از دامنهٔ بیرونی دسترسی دارد. این دسترسی حتی پس از پایان اجرای greeting حفظ می‌شود.


Closure با داده‌های قابل‌تغییر:


function counter(step = 1) {
  var count = 0;
  return function increaseCount() {
    count = count + step;
    return count;
  };
}
var incBy1 = counter(1);
var incBy3 = counter(3);

incBy1(); // 1
incBy1(); // 2
incBy3(); // 3
incBy3(); // 6

تابع increaseCount به متغیرهای count و step دسترسی دارد و مقدار آن‌ها را حفظ و تغییر می‌دهد.


Closure در کدهای ناهم‌زمان:


function getSomeData(url) {
  ajax(url, function onResponse(resp) {
    console.log(`Response (from ${url}): ${resp}`);
  });
}

تابع onResponse به url دسترسی دارد، حتی پس از پایان اجرای getSomeData.


Closure در حلقه‌ها:


for (let [idx, btn] of buttons.entries()) {
  btn.addEventListener("click", function onClick() {
    console.log(`Clicked on button (${idx})!`);
  });
}

هر تابع onClick به متغیر idx مربوط به همان تکرار دسترسی دارد.


this چیست؟


this یکی از مفاهیم قدرتمند و در عین حال گیج‌کننده در JS است. برخلاف تصور رایج، this به تابع یا شیء خاصی اشاره ندارد، بلکه به زمینهٔ اجرایی در لحظهٔ فراخوانی تابع وابسته است.


مثال:


function classroom(teacher) {
  return function study() {
    console.log(`${teacher} says to study ${this.topic}`);
  };
}
var assignment = classroom("Kyle");

assignment(); // Kyle says to study undefined

در اینجا، چون تابع بدون زمینهٔ اجرایی فراخوانی شده، this.topic برابر undefined است.


فراخوانی با زمینهٔ اجرایی:


var homework = {
  topic: "JS",
  assignment: assignment
};
homework.assignment(); // Kyle says to study JS

تابع به‌عنوان متد شیء homework فراخوانی شده و this به آن شیء اشاره دارد.


فراخوانی با call:


var otherHomework = {
  topic: "Math"
};
assignment.call(otherHomework); // Kyle says to study Math

با استفاده از call می‌توان this را به شیء دلخواه نسبت داد.


جمع‌بندی


Closure به توابع اجازه می‌دهد متغیرهای بیرونی را حفظ و استفاده کنند، حتی پس از پایان دامنهٔ اصلی. this به زمینهٔ اجرایی وابسته است و در لحظهٔ فراخوانی تعیین می‌شود. شناخت دقیق این دو مفهوم، پایه‌ای ضروری برای نوشتن کدهای حرفه‌ای در جاوااسکریپت است.


نوشته و پژوهش‌شده توسط دکتر شاهین صیامی

مقالات مرتبط

نحوهٔ میزبانی مستقل اپلیکیشن Next.js – پیکربندی، کشینگ، و استراتژی‌های استقرار

nextjs-self-hosting-deployment-cache-isr-proxy-env

ادامه

مقایسه‌های شرطی تبدیل‌پذیر و کلاس‌های پروتوتایپی در جاوااسکریپت – درک دقیق رفتار شرطی و ساختارهای ارث‌بری

این مقاله دو موضوع مهم از ضمیمهٔ A کتاب YDKJSY را بررسی می‌کند: نحوهٔ تبدیل نوع در عبارات شرطی مانند if و while، و الگوی کلاس‌های پروتوتایپی به‌عنوان پیش‌زمینه‌ای برای کلاس‌های ES6. با مثال‌های عملی، تفاوت بین مقایسه‌های دقیق و تبدیل‌پذیر، و نحوهٔ تفویض رفتار از طریق زنجیرهٔ پروتوتایپ روشن می‌شود.

ادامه

در جاوااسکریپت – تفاوت مقدار و مرجع، و فرم‌های متنوع تعریف تابع

در جاوااسکریپت – تفاوت مقدار و مرجع، و فرم‌های متنوع تعریف تابع

ادامه

پروتوتایپ‌ها در جاوااسکریپت – زنجیرهٔ ارجاع، تفویض ویژگی‌ها، و نقش this در رفتار پویا

پروتوتایپ‌ها در جاوااسکریپت مکانیزمی برای ارجاع ویژگی‌ها بین اشیاء هستند. این مقاله به تعریف زنجیرهٔ پروتوتایپ، نحوهٔ تفویض ویژگی‌ها، تفاوت بین دسترسی و انتساب، و نقش کلیدی this در فراخوانی متدهای ارجاع‌شده می‌پردازد. درک این مفاهیم برای طراحی شی‌گرا و رفتارهای پویا در JS ضروری است.

ادامه

تکرار در جاوااسکریپت – الگوی Iterator، ساختارهای قابل‌تکرار، و مصرف استاندارد داده‌ها

تکرار در جاوااسکریپت – الگوی Iterator، ساختارهای قابل‌تکرار، و مصرف استاندارد داده‌ها

ادامه

ماژول‌ها در جاوااسکریپت – از الگوی کلاسیک تا ES Modules و تفاوت‌های ساختاری

ماژول‌ها در جاوااسکریپت مانند کلاس‌ها برای گروه‌بندی داده و رفتار در واحدهای منطقی طراحی شده‌اند. این مقاله به بررسی الگوی کلاسیک ماژول‌ها با توابع کارخانه‌ای، تفاوت آن با کلاس‌ها، و معرفی ES Modules در ES6 می‌پردازد. همچنین به نحوهٔ استفاده، صادرات، و وارد کردن ماژول‌ها و تفاوت در نمونه‌سازی اشاره می‌شو

ادامه