از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
راهنمای بسته شدن جاوا اسکریپت Closures یک مفهوم تا حدی انتزاعی از زبان جاوا اسکریپت است و به سمت کامپایلر برنامه نویسی پنهان می شود. با این حال، درک اینکه جاوا اسکریپت چگونه توابع، توابع تودرتو، حوزهها و محیطهای واژگانی را تفسیر میکند، برای استفاده از پتانسیل کامل آن ضروری است. در این مقاله سعی می کنیم مفاهیم گفته شده را ابهام زدایی کنیم و یک …
سرفصلهای مطلب
معرفی
بسته شدن مفهومی تا حدی انتزاعی از زبان جاوا اسکریپت است و به سمت کامپایلر برنامه نویسی سرازیر می شود. با این حال، درک اینکه جاوا اسکریپت چگونه توابع، توابع تودرتو، حوزهها و محیطهای واژگانی را تفسیر میکند، برای استفاده از پتانسیل کامل آن ضروری است.
در این مقاله سعی خواهیم کرد مفاهیم مذکور را ابهام زدایی کرده و ارائه کنیم یک راهنمای ساده برای بسته شدن جاوا اسکریپت.
بسته شدن چیست؟
ابتدا اجازه دهید نگاهی به تعریف رسمی MDN از بسته شدن بیندازیم:
بسته شدن ترکیبی از یک تابع همراه (محصور) با ارجاع به وضعیت اطراف آن (محیط واژگانی) است. به عبارت دیگر، بسته شدن به شما امکان دسترسی به محدوده عملکرد بیرونی از یک تابع داخلی را می دهد.
به عبارت ساده تر، بسته شدن تابعی است که به محدوده عملکرد بیرونی دسترسی دارد. برای درک این موضوع، بیایید نگاهی به روش عملکرد دامنه ها در جاوا اسکریپت بیندازیم.
دامنه در جاوا اسکریپت
محدوده تعیین می کند که کدام متغیرها در یک زمینه مشخص قابل مشاهده هستند یا می توانند به آنها ارجاع دهند. دامنه به طور کلی به دو نوع تقسیم می شود – دامنه جهانی و Local محدوده:
-
دامنه جهانی – متغیرهایی که خارج از یک تابع تعریف شده اند. متغیرهای این محدوده را می توان از هر نقطه ای از برنامه در دسترس قرار داد و تغییر داد، از این رو به آن “جهانی” می گویند.
-
Local محدوده – متغیرهای تعریف شده در داخل یک تابع. این متغیرها مختص تابعی هستند که در آن تعریف می شوند، از این رو “محلی” نامیده می شوند.
بیایید نگاهی به یک متغیر جهانی و محلی در جاوا اسکریپت بیندازیم:
let name = "Joe";
function hello(){
let message = "Hello";
console.log(message + " " +name);
}
در مثال بالا، محدوده name
جهانی است، یعنی در هر جایی قابل دسترسی است. از سوی دیگر، message
در داخل یک تابع تعریف شده است، دامنه آن محلی است hello()
تابع.
جاوا اسکریپت استفاده می کند محدوده واژگانی وقتی صحبت از محدوده عملکرد می شود. به این معنی که محدوده یک متغیر با موقعیت تعریف آن در کد منبع تعریف می شود. این به ما امکان می دهد تا متغیرهای سراسری را در محدوده های کوچکتر ارجاع دهیم. یک متغیر محلی می تواند از یک متغیر سراسری استفاده کند، اما برعکس امکان پذیر نیست.
بر
function outer(){
let x = 10;
function inner() {
let y = 20;
console.log(x);
}
inner();
console.log(y)
}
outer();
این کد نتیجه می دهد:
10
error: Uncaught ReferenceError: y is not defined
را inner()
تابع می تواند مرجع باشد x
از آنجایی که در تعریف شده است outer()
تابع. با این حال console.log(y)
بیانیه در outer()
تابع نمی تواند به y
متغیر چون در تعریف شده است inner()
محدوده عملکرد
علاوه بر این، در این سناریو:
let x = 10;
function func1(){
console.log(x);
}
function func2() {
let x = 20;
func1();
}
func2();
خروجی خواهد بود:
10
وقتی زنگ میزنیم func1()
از درون func2()
، ما یک متغیر با محدوده محلی داریم x
. با این حال، این متغیر کاملاً بی ربط است func1()
چون در دسترس نیست func1()
.
بدین ترتیب، func1()
بررسی می کند که آیا یک متغیر سراسری با آن شناسه در دسترس است یا خیر، و از آن استفاده می کند و در نتیجه مقدار 10
.
بسته های زیر کاپوت
بسته شدن تابعی است که حتی پس از بازگشت تابع خارجی به متغیرهای والد خود دسترسی دارد. به عبارت دیگر، بسته شدن دارای سه حوزه است:
- Local محدوده – دسترسی به متغیرها در محدوده خودش
- محدوده عملکرد والد – دسترسی به متغیرهای درون والد آن
- دامنه جهانی – دسترسی به متغیرهای جهانی
بیایید با ساختن تابعی که تابع دیگری را برمی گرداند نگاهی به بسته شدن در محل کار بیندازیم:
function outer() {
let x = 3
return function inner(y) {
return x*y
}
}
let multiplyByThree = outer();
console.log(multiplyByThree(2));
این نتیجه در:
6
اگر یک کار را انجام دهیم:
console.log(multiplyByThree);
به ما خوش آمد می گوید:
function inner(y) { return x * y; }
بیایید گام به گام کد را مرور کنیم تا ببینیم در زیر کاپوت چه اتفاقی می افتد:
- را
outer()
تابع در محدوده جهانی تعریف شده است. outer()
فراخوانی می شود و تابعی را برمی گرداند که به آن اختصاص داده شده استmultiplyByThree
.- زمینه اجرای جدید برای ایجاد شده است
outer()
.- متغیر
x
روی 3 تنظیم شده است.
- متغیر
- تابعی به نام را برمیگرداند
inner()
. - ارجاع به
inner()
اختصاص داده شده استmultiplyByThree
. - با پایان اجرای تابع خارجی، تمام متغیرهای موجود در محدوده آن حذف می شوند.
- زمینه اجرای جدید برای ایجاد شده است
- نتیجه فراخوانی تابع
multiplyByThree(2)
به سیستم وارد شده است console.inner()
با احضار شده است2
به عنوان استدلال بنابراین،y
تنظیم شده است2
.- مانند
inner()
زنجیره دامنه تابع والد خود را حفظ می کند، در زمان اجرا همچنان به مقدارx
. - برمی گردد
6
که به سیستم وارد می شود console.
در نتیجه، حتی پس از بیرونی عملکرد متوقف می شود، درونی تابع به متغیرهای تعریف شده در حوزه دسترسی دارد بیرونی تابع.
تجسم بسته شدن
بسته شدن را می توان از طریق توسعه دهنده تجسم کرد console:
function outer() {
let x = 3
return function inner(y) {
return x*y
}
}
let multiplyByThree = outside();
console.dir(multiplyByThree);
با اجرای کد بالا در توسعه دهنده console، می بینیم که به متن دسترسی داریم inner(y)
. با بررسی دقیق تر، می توانیم ببینیم که زمینه آن یک است ((Scopes))
آرایه ای که شامل هر سه محدوده مورد بحث ما است.
ببینید، آرایه دامنه ها شامل محدوده تابع والد خود است که شامل x = 3
:
موارد استفاده رایج
بستهها مفید هستند زیرا به ما کمک میکنند دادهها را با توابعی که عمل میکنند خوشهبندی کنیم روی آن داده ها این ممکن است برای برخی از شما که با برنامه نویسی شی گرا (OOP) آشنا هستید زنگ بزند. در نتیجه، میتوانیم در هر جایی که ممکن است از یک شی استفاده کنیم، از بستهها استفاده کنیم.
یکی دیگر از موارد مهم استفاده از بسته شدن زمانی است که ما به متغیرهای خود نیاز داریم خصوصی، به عنوان متغیرهایی که در محدوده یک بسته تعریف شده اند، برای توابع خارج از آن محدودیت ندارند. در عین حال، بسته ها به متغیرهای زنجیره دامنه خود دسترسی دارند.
برای درک بهتر این موضوع به مثال زیر نگاه می کنیم:
const balance = (function() {
let privateBalance = 0;
return {
increment: function(value){
privateBalance += value;
return privateBalance;
},
decrement: function(value){
privateBalance -= value;
return privateBalance;
},
show: function(){
return privateBalance;
}
}
})()
console.log(balance.show()); // 0
console.log(balance.increment(500)); // 500
console.log(balance.decrement(200)); // 300
در این مثال یک متغیر ثابت تعریف کرده ایم balance
و آن را به عنوان مقدار بازگشتی تابع ناشناس خود تنظیم کنید. توجه کنید که privateBalance
فقط با فراخوانی متدها قابل تغییر است روی balance
.
نتیجه
اگرچه بستن یک مفهوم نسبتاً خاص در جاوا اسکریپت است، اما ابزار مهمی در جعبه ابزار خوب توسعه دهندگان جاوا اسکریپت است. می توان از آنها برای اجرای ظریف راه حل هایی استفاده کرد که در غیر این صورت یک سفارش طولانی خواهد بود.
در این مقاله ابتدا کمی با اسکوپ ها و روش پیاده سازی آنها در جاوا اسکریپت آشنا شده ایم. سپس از این دانش برای درک روش عملکرد بستهها در زیر کاپوت و روش استفاده از آنها استفاده کردیم.
(برچسبها برای ترجمه)# جاوا اسکریپت
منتشر شده در 1403-01-18 10:01:03