متن خبر

بسته شدن در جاوا اسکریپت چگونه کار می کند؟ با مثال کد توضیح داده شده است

بسته شدن در جاوا اسکریپت چگونه کار می کند؟ با مثال کد توضیح داده شده است

شناسهٔ خبر: 469860 -




سالی و جو دو پرنده عشق هستند. آنها همه چیز را با یکدیگر به اشتراک گذاشتند و به زودی تقریباً غیرممکن بود که فکر کنیم چیزی بین آنها وجود دارد. یک روز، آنها دعوا کردند که منجر به جدایی شد.

برای جو سخت بود و او خواهان "بستن" بود. اگرچه سالی پیش از این حرکت کرده بود، اما جو با صرف زمان برای فکر کردن در کل تجربه، یادآوری «خاطرات مشترک» و درون نگری مناسب به پایان رسید. با وجود اینکه این رابطه به پایان رسیده بود، جو هنوز چیزی داشت که او را به یاد سالی می انداخت و او با این حرف خونسرد بود.

داستان به پایان می رسد.

اگر این اولین بار است که اصطلاح "بسته شدن" را می شنوید، افتخار می کنم که معنی آن را به شما بگویم.

بسته شدن صرفاً عمل به پایان رساندن چیزی است. بسته شدن در یک رابطه به احساس آرامش و درک شما پس از پایان رابطه اشاره دارد. این همان احساس "رها کردن" و توانایی ادامه دادن است.

برای برخی از افراد، بستن شامل نگه داشتن یک "خاطره مشترک" با طرف مقابل یا چیزی (شاید یک مورد) است که آنها را به یاد طرف مقابل می اندازد.

اکنون که با اصطلاح بسته شدن آشنا شدید همانطور که به انسان مربوط می شود، بیایید سعی کنیم آن را از نظر رابطه بین توابع در جاوا اسکریپت درک کنیم.

در جاوا اسکریپت، بسته شدن زمانی ایجاد می شود که یک تابع دسترسی به منابع (های) اعلام شده در محدوده والد خود را حتی پس از حذف تابع والد از پشته تماس حفظ کند.

نکته : در جاوا اسکریپت، وقتی گفته می‌شود تابعی از پشته پاپ‌آف/حذف شده است، به این معنی است که طول عمر آن تابع به پایان رسیده است (در حال اجرا است) و تمام منابع آن از حافظه حذف شده است و دیگر در دسترس نیست

به پشته تماس مانند دنیا فکر کنید، در حالی که والدین و فرزند دو موجودیت در جهان هستند.

در این حالت، parent تابعی است که اجرا را به پایان رسانده است و منطقاً همه چیز در مورد آن باید دور از دسترس باشد اما به دلیل مفهوم بسته شدن، حتی زمانی که رابطه بین توابع parent و child به پایان رسیده است. یعنی وقتی والدین از پشته بیرون می‌آیند (از دنیا حذف می‌شوند)، تابع فرزند هنوز همه چیزهایی را که با هم به اشتراک گذاشته‌اند به خاطر می‌آورد.

توجه : هر چیزی که آنها با هم به اشتراک گذاشتند همانطور که در بالا استفاده شد به سادگی به معنی متغیرهای اعلام شده در تابع parent است که توسط تابع child استفاده می شود.

 function parent () { let a = "Az"; return function child () { console.log(a); } }

در قطعه کد بالا، متغیر a چیزی است که توابع parent و child با هم به اشتراک می گذارند.

پس حتی زمانی که parent از پشته تماس حذف می شود، child هنوز مقدار a را به خاطر می آورد تا زمانی که زنده است

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

فرو رفتن عمیق در مفهوم بسته شدن.

برای درک واقعی بسته شدن در جاوا اسکریپت، باید با مفاهیم زیر آشنا باشید:

    مفهومی از توابع شهروندان درجه یک در جاوا اسکریپت هستند. این بدان معنی است که:

توابع را می توان به عنوان مقادیر به متغیرها اختصاص داد

 const getName = function () { return 'Allice' };

اکنون می‌توانید به سادگی تابع getName درست مانند هر تابع دیگری با استفاده از پرانتز مانند getName() فراخوانی کنید.

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

توابع را می توان به عنوان آرگومان به توابع دیگر منتقل کرد

 setTimeout(getName, 5000)

همانطور که در قطعه کد بالا مشاهده می کنید، در حین فراخوانی تابع setTimeout ، تابع getName را به عنوان آرگومان به آن ارسال کردیم. باز هم به این دلیل است که توابع به سادگی اشیایی هستند که قابل فراخوانی هستند.

توجه داشته باشید که وقتی تابع getName به تابع setTimeout می‌دهیم، آن را فراخوانی نمی‌کنیم. ما به سادگی تابع را به عنوان یک مقدار منتقل می کنیم.

اگر تابع را فراخوانی می‌کردیم، به جای آن مقدار بازگشتی آن را ارسال می‌کردیم و این تفاوت قابل توجهی است.

من همچنین می خواهم به شما توجه کنم که ذکر نام یک تابع به سادگی ارجاع به آن تابع است. در پشت صحنه، نام تابع با خود تابع جایگزین می شود.

یعنی این کد setTimeout(getName, 5000) معادل کد زیر است.

 setTimeout(function () { return 'Allice' }, 5000)

نام تابع در حین اجرا با خود تابع جایگزین می شود درست مانند نام متغیر معمولی که در حین اجرا با مقدار آن جایگزین می شود.

توابع را می توان از توابع دیگر برگرداند.

 function multiplyBy (numberToMultiplyBy) { return function (numberToMultiply) { return numberToMultiply * numberToMultiplyBy } }

با نگاهی دقیق به قطعه کد بالا، متوجه خواهید شد که ما تابعی به نام multiplyBy داریم که در حین فراخوانی، یک آرگومان را انتظار دارد و یک تابع جدید برمی گرداند.

نکته جالب توجه در اینجا این است که وقتی تابع برگردانده شده را فراخوانی می کنیم، انتظار آرگومان نیز دارد، اما این بار، آرگومان ارسال شده به تابع multiplyBy اصلی ( numberToMultiplyBy ) را به خاطر می آورد، سپس مقدار ارسال شده در خود ( numberToMultiply ) را ضرب می کند. مقدار به تابع والد خود ارسال می شود و نتیجه را برمی گرداند.

کد زیر را با دقت مشاهده کنید که از تابع مرتبه بالاتر multiplyBy استفاده می کند:

 const multiplyByTwo = multiplyBy(2) const result = multiplyByTwo(8) console.log(result) // 16

2. مفهوم توابع مرتبه بالاتر: این دومین مفهومی است که برای درک بسته شدن باید از آن آگاه باشید.

تابع مرتبه بالاتر تابعی است که:

تابعی را به عنوان آرگومان می پذیرد. به عنوان مثال: setTimeout ، Promise و غیره.

تابعی را برمی‌گرداند. به عنوان مثال: تابع multiplyBy اعلام شده در بالا.

یا موارد اول و دوم بالا را برآورده می کند.

اکنون که متوجه شدید که توابع شهروندان درجه یک هستند و اجرای یک تابع درجه بالاتر را مشاهده کرده اید، می توانیم در مورد بسته شدن صحبت کنیم.

به یاد داشته باشید که بسته شدن زمانی اتفاق می‌افتد که یک تابع فرزند یک مقدار یا منبعی را که به تابع والد خود تعلق دارد، ارجاع می‌دهد/به خاطر می‌آورد، حتی پس از حذف تابع والد از پشته فراخوانی.

این کد را در نظر بگیرید:

 function sally () { let age = 64; return function joe () { const data = { name: "Joe", parentName: "Sally", parentAge: age } return data } }

در قطعه کد بالا می توانیم مشاهده کنیم که:

sally تابع والد است و یک محدوده را اعلام می کند

age متغیری است که در محدوده sally اعلام شده است

joe تابعی است که در محدوده sally زندگی می کند و توسط تابع sally برگردانده می شود. همچنین باید توجه داشته باشید که:
- joe محدوده خود را تعریف می کند که یک محدوده کودک است را sally محدوده
- در محدوده joe ، به age متغیری که متعلق به دامنه sally است اشاره می کنیم (این جایی است که بسته شدن اتفاق می‌افتد زیرا joe به منبع/متغیری اشاره می‌کند یا آن را نگه می‌دارد که متعلق به sally است).

از آنجایی که joe ارجاعی به متغیر age دارد که به sally تعلق دارد، حتی زمانی که sally از پشته تماس خارج شده و دامنه آن کنار گذاشته شده است، joe به دلیل مفهوم بسته شدن، دسترسی به متغیر age را حفظ خواهد کرد.

پس در کد زیر:

 const joe = sally() // sally is invoked and returns the joe function const joeyData = joe() // joe function is invoked and returns an object console.log(joeyData) // we log the object returned.

می‌توانید مشاهده کنید که حتی اگر sally فراخوانی می‌شود و از پشته بیرون می‌آید، وقتی joe فراخوانی می‌کنید و مقدار بازگشتی joe به کنسول وارد می‌کنید، همچنان age سالی را در طول اجرا به یاد می‌آورد (که می‌توانیم در شیء برگشتی به آن دسترسی پیدا کنیم. مانند joeyData.parentAge ).

خلاصه

هنگامی که یک تابع فرزند به متغیرهای استفاده شده در محدوده والد خود اشاره می کند، بسته شدن اتفاق می افتد.
بسته شدن مانند یک جعبه حافظه است که تمام موارد حوزه والد را که از دامنه فرزند به آنها ارجاع می شود، ذخیره می کند.

نگاهی به اسلایدهای زیر باید دانشی را که تا کنون به دست آورده‌اید تقویت کند و امیدواریم همه چیز سر جای خود قرار گیرد.

بسته ها باز شده است؟ مهارت‌های جاوا اسکریپت خود را با آموزش‌های توسعه کامل‌تر در کانال YouTube من افزایش دهید. اکنون برای فهرست پخش بعدی من در مورد مفاهیم اساسی جاوا اسکریپت مشترک شوید!

با تشکر برای خواندن! کد نویسی مبارک!

خبرکاو

ارسال نظر

دیدگاه‌ها بسته شده‌اند.


تبليغات ايهنا تبليغات ايهنا

تمامی حقوق مادی و معنوی این سایت متعلق به خبرکاو است و استفاده از مطالب با ذکر منبع بلامانع است