من میدانم که هیچ نمیدانم.
اسکوپ (scope) در جاوااسکریپت چیست؟
سلام دوستان. توی این قسمت میخوایم یکی دیگه از مفاهیم مهم جاوااسکریپت رو بررسی کنیم. مفهومی که درک کردن صحیح اون باعث میشه با خطاهای کمتری رو به رو بشیم و با خیال راحتتر کدنویسی کنیم.
امروز میخوایم درباره اسکوپ (Scope) توی جاوااسکریپت صحبت کنیم.
توی این قسمت یاد میگیریم که:
- اسکوپ یا حوزه چیه؟
- بلاک چیه؟
- اسکوپ سراسری (Global Scope) چیه؟
- اسکوپ محلی (Local Scope) چیه؟
- اسکوپ بلاکی (Block Scope) چیه؟
اسکوپ یا حوزه چیه؟
بطور کلی اسکوپ (Scope) به قسمتهایی از برنامه گفته میشه که یک متغیر، تابع، آبجکت و ... قابل دسترسی هست. کد زیر رو اجرا کنید:
const x = 10;
function getX() {
alert(x);
const y = 20;
}
getX();
alert(y); // error
توی تابع getX
تونستیم به متغیر x
که بیرون از تابع تعریف شده دسترسی داشته باشیم و اون رو alert
کنیم. همچنین توی این تابع یک متغیر تعریف کردیم به اسم y
و اون رو داریم توی خط آخر alert
میکنیم. اما اینجا خطا میگیریم که y
تعریف نشده. چرا اینطوری میشه؟ به دلیل قوانینی که اسکوپها توی جاوااسکریپت دارن! توی این قسمت میریم که این قوانین رو بررسی کنیم.
توی جاوااسکریپت ۳ نوع اسکوپ داریم:
- اسکوپ سراسری (Global Scope)
- اسکوپ محلی (Local Scope)
- اسکوپ بلاکی (Block Scope)
قبل از شروع یک چیز رو باید بررسی کنیم: بلاک یا Block
بلاک چیه؟
به فضایی از کد که بین دو براکت { ... }
قرار میگیره میگیم بلاک. مثلاً فضای داخل if
،while
و ... :
if (...) {
/*
Block
*/
}
for (...) {
/*
Block
*/
}
{
/*
Block
*/
}
حالا بریم انواع اسکوپها رو بررسی کنیم.
اسکوپ سراسری (Global Scope)
به بیرونیترین قسمت یک برنامه جاوااسکریپتی میگیم اسکوپ سراسری. متغیرهایی که توی این اسکوپ تعریف میشن، همه جای برنامه قابل دسترسی هستن. مثال زیر رو ببینید:
// Global Scope
const name = "Diego"
function func() {
alert(name); // Diego
}
func();
توی این مثال متغیر name
توی اسکوپ سراسری تعریف شده. چون محدود شده درون هیچ تابع و بلاکی نیست و در بیرونیترین حالت قرار داره. متغیرهایی که توی اسکوپ سراسری تعریف میشن، توی توابع هم قابل دسترسی هستن. پس کد بالا بدون مشکل اجرا میشه.
متغیرهای سراسری در سراسر برنامه قابل دسترسی هستن.
اسکوپ محلی (Local Scope)
متغیرهایی که توی یک تابع تعریف میشن، اسکوپ لوکال (محلی) دارن و فقط درون خود تابع قابل دسترسی هستن:
// Global Scope
function getUser() {
// Local Scope
const user = "Mario"
alert(user);
}
getUser(); // Mario
alert(user); // ReferenceError: user is not defined
با اجرا شدن کد بالا alert
توی خط ۷ به درستی کار میکنه. چون متغیر user
توی همون اسکوپ هست. اما alert
خط آخر خطا میده چون متغیر user
توی این اسکوپ وجود نداره. به اسکوپ لوکال به اصطلاح Function Scope هم گفته میشه.
توابع تو در تو چطور؟
مثال زیر رو در نظر بگیرید:
// Global Scope
function func1() {
// Local Scope #1
const name = "Mario"
function func2() {
// Local Scope #2
const lastname = "Doe"
alert(`${name} ${lastname}`);
}
func2();
}
func1(); // John Doe
همونطور که میبینیم یک تابع به اسم func2
داخل یک تابع دیگه به اسم func1
تعریف شده. طبق قوانین اسکوپها، توابع داخلی میتونن به متغیرهای اسکوپ بیرونی خودشون دسترسی داشته باشن. پس تابع func2
به متغیر name
که بیرون از این تابع تعریف شده دسترسی داره. اما عکس این قضیه صادق نیست. اسکوپهای بیرونی نمیتونن به اعضای اسکوپهای داخلی دسترسی داشته باشن:
unction func1() {
function func2() {
const x = 10;
}
alert(x);
}
func1(); // ReferenceError: x is not defined
اسکوپ بلاکی (Block Scope)
همونطور که گفتیم به فضای بین دو براکت میگیم بلاک. متغیرهایی که با let
و const
توی یک بلاک تعریف میشن فقط توی همون بلاک قابل دسترسی هستن:
{
let x = 29;
}
alert(x) // ReferenceError: x is not defined
اما برای var
اینطوری نیست. متغیری که با var
توی یک بلاک تعریف بشه، بیرون بلاک هم قابل دسترسی هست:
{
var x = 12;
}
alert(x) // 12
در واقع اسکوپی که یک بلاک درست میکنه همون اسکوپ محلی هست. یعنی فقط همونجا قابل دسترسی هست:
const x = 10;
{
const x = 20;
alert(x); // 20
}
alert(x); // 10
با اجرای کد بالا میبینیم که متغیر x
داخل بلاک هیچ تداخلی با x
که بیرون تعریف شده نداره. این دو در واقع دو متغیر جدا هستن.
اگه بلاکهای تو در تو داشته باشیم، اعضای یک بلاک بیرونی نمیتونه به اعضای بلاکهای داخلی دسترسی داشته باشه؛ اما اعضای داخلی میتونن به اعضای بیرونی دسترسی داشته باشن:
const x = 1;
{
const y = 2;
{
alert(x); // ok
alert(y); // ok
const z = 3;
}
alert(z); // error
}
alert(y); // error
خب دوستان این قسمت هم به پایان رسید. باید بدونیم که با یادگیری مهمترین مفاهیم هر زبان هست که میتونیم یک برنامهنویس و توسعهدهندهٔ با ارزش بشیم.
منابع :
مطلبی دیگر از این انتشارات
ترید، از واقعیت تا رویا
مطلبی دیگر از این انتشارات
بررسی انواع هزینه ها در معاملات ارز دیجیتال
مطلبی دیگر از این انتشارات
معرفی و بررسی شبکه Efinity و توکن EFI