بسته شدن جاوا اسکریپت به سادگی توضیح داده شد – انجمن DEV
بسته شدن یکی از ستون های اصلی جاوا اسکریپت است. این نیز سوال مصاحبه محبوب است. بنابراین، امروز توضیح خواهیم داد که Closure چیست و به لطف آنها چه کاری می توانیم انجام دهیم.
درک بسته شدن
به زبان ساده، بسته شدن امکان دسترسی به متغیرهای خارج از تابع را فراهم می کند. Closure تابعی است که می تواند به متغیرهای واقع در محدوده تابع در زمانی که تابع تعریف شده است دسترسی داشته باشد و آنها را دستکاری کند. سپس اگر تابع در زمانی فراخوانی شود که محدوده خارجی با متغیر از قبل وجود نداشته باشد، تابع همچنان دسترسی به متغیر را حفظ می کند. این یک حباب در اطراف تابع ما ایجاد می کند، همه متغیرها را در زمانی که تابع ایجاد شده است در یک محدوده نگه می دارد.
const outerFunction = (outerVariable) => {
const innerFunction = (innerVariable) => {
console.log('outerVariable:', outerVariable);
console.log('innerVariable:', innerVariable);
}
return innerFunction;
}
const newFunction = outerFunction('outside');
newFunction('inside'); // logs outerVariable: outside innerVariable: inside
نمونه های عملی
بستن در جاوا اسکریپت برای بسیاری از اصول استفاده می شود، زمانی که ما حتی متوجه استفاده از آنها در زیر هود نیستیم.
گیرنده و تنظیم کننده
جاوا اسکریپت از متغیرهای خصوصی پشتیبانی نمیکند، اما میتوانیم با استفاده از Closure به رفتار مشابهی دست یابیم. وقتی نمیخواهیم اجازه دسترسی مستقیم به یک متغیر را بدهیم، میتوانیم دسترسیها – گیرندهها و تنظیمکنندهها – ایجاد کنیم تا آنها را خارج از تابع فعال کنیم. بیایید در مثال زیر آن را بهتر توصیف کنیم:
const post = () => {
let likes = 0; // private variable
return {
getLikes: () => {
return likes;
},
like: () => {
return likes++;
};
}
}
var post1 = post();
post1.like();
console.log(post1.likes); // undefined
console.log(post1.getLikes()); // 1
var post2 = post();
console.log(post2.getLikes()); // 0
ابتدا متغیر خصوصی را اعلام می کنیم likes
داخل سازنده تابع likes
در محدوده عملکرد قرار دارد و از خارج قابل دسترسی نیست. سپس متد accessor را برای تعداد لایک ها ایجاد می کنیم. با تعریف گیرنده، به مقدار دسترسی فقط خواندنی می دهیم. روش دوم برای افزایش تدریجی تعداد لایک است. هیچ کس نمی تواند ارزش را بیشتر از آنچه ما اجازه می دهیم تغییر دهد. و در نهایت، ورود به کنسول به شما این امکان را میدهد که ببینید ما به لایکها دسترسی مستقیم نداریم اما میتوانیم مقدار را با تماس بخوانیم. getLikes()
یا با تماس تعداد لایک ها را افزایش دهید like()
.
پاسخ به تماس به عنوان بسته شدن
این یک مثال عملی دیگر از زمانی است که ما واکشی ناهمزمان دادهها و سپس بهروزرسانی رابط کاربری یا ورود به سیستم را انجام میدهیم. بیایید نگاهی به مثال زیر بیاندازیم.
const fetchData = (url, callback) => {
// It is simulating an asynchronous operation
setTimeout(() => {
const data = { name: 'Adam', age: 20 };
callback(data);
}, 2000);
}
const processUserData = (user) => {
console.log('Name:', user.name);
console.log('Age:', user.age);
}
fetchData('https://example.com/api/user', processUserData);
fetchData
تابع دو پارامتر می گیرد. اولین مورد یک URL است که از آن داده ها را واکشی می کنیم. مورد دوم تماس برگشتی است که پس از انجام تماس ناهمزمان فراخوانی می شود. processUserData
تابع تابع تماس ما است و همچنین بسته شدن است! وقتی که fetchData
اجرا می شود سپس setTimeout فراخوانی می شود و تماس برگشتی به داده های کاربر خارجی دسترسی دارد. و دسترسی حتی پس از اجرای آن باقی می ماند fetchData
تمام شده است.
این یک روش متداول است که چگونه پاسخ تماس میتواند به دادههای بازگردانده شده توسط واکشی همگامسازی دسترسی پیدا کند و سپس کارهای مختلفی را انجام دهد، مثلاً رابط کاربری را بهروزرسانی کند.
عیب
همانطور که می بینید، بزرگترین عیب این است که بسته شدن مجموعه ای از متغیرهای دیگر را به همراه دارد. این می تواند منجر به مصرف غیر ضروری حافظه در صورت استفاده آزاد شود.
خلاصه
ما بسته شدن را به عنوان تابعی توصیف کردیم که به متغیرهای خارجی دسترسی دارد که در زمان تعریف بسته شدن در محدوده بودند. بسته ها به عنوان دسترسی به متغیرهای خصوصی – دریافت کننده ها و تنظیم کننده ها – یا همراه با یک تابع تماس برای به روز رسانی رابط کاربری بر اساس داده های واکشی ناهمزمان استفاده می شوند.