من میدانم که هیچ نمیدانم.
بررسی (let - var - const) در جاوااسکریپت
درود دوستان. توی این پست روشهای مختلف ساخت متغیرها رو بطور مفصل با هم بررسی میکنیم.
کلی ویژگی جالب و جدید توسط ES6 به جاوااسکریپت اضافه شده و این زبان رو محبوب تر از همیشه کرده. در کنار var
که تنها روش موجود در جاوااسکریپت بود، ES6 دوتا روش جدید برای ساخت متغیرها معرفی کرده که let
و const
هستن. اگه تا الان از var
استفاده میکردین و کاربرد let
و const
رو نمیدونین، شاید از خودتون بپرسین من که تا الان از var
استفاده میکردم و هیچ مشکلی وجود نداشت، پس چرا باید از let
استفاده کنم؟ بهتره که این مقاله رو خوب بخونین؛ چون پیشنهاد میشه کم کم با var خداحافظی کنین.
قبل از شروع بهتره با چند تا تعریف آشنا بشیم.
۱. اسکوپ (Scope) یا حوزه
اسکوپ (Scope) یا حوزه، به جاهایی گفته میشه که متغیرها قابل دسترسی و استفاده هستن
یعنی یک متغیر توی چه جاهایی قابل دسترسی هست. مثلا توی تابع یا کلاس.
متغیرهای سراسری دارای حوزه Global هستن (Global Scope). یعنی همه جا در دسترس هستن.
۲. هویستینگ (Hoisting)
این واژه توی زبان پارسی یعنی بالا بردن یه چیزی.
هویستینگ Hoisting توی جاوااسکریپت مکانیزمی هست که باعث میشه قبل از اجرای برنامه، متغیرها و توابع، به بالاترین سطح حوزه خودشون جابجا بشن.
با Hoisting توی هر آیتم var و let و const بیشتر آشنا میشیم. حالا هر ۳ مورد رو میتونیم بهتر بررسی کنیم.
تعریف متغیر با var
قبل از اینکه ES6 معرفی بشه، تنها راه موجود ساخت متغیرها تو جاوااسکریپت var
بود. استفاده از var
باعث به وجود اومدن مشکلاتی میشد و به همین دلیل به وجود اومدن یک راه جدید رو الزامی کرد. قبل از اینکه درباره این مشکلات صحبت کنیم، بیاین درباره var
بیشتر بدونیم.
متغیرهایی که با var
تعریف میشن، میتونن یا حوزه سراسری داشته باشن یا لوکال (محلی). یک متغیر وقت بیرون از یک تابع تعریف شده باشه حوزه سراسری داره. یعنی وقتی یک متغیر با var
بیرون از یک تابع تعریف شده باشه، توی همه جای برنامه در دسترس هست. حتی درون تابع:
var x = "This is a book"
function cookie() {
alert(x);
}
cookie(x); // This is a book
توی مثال بالا، ما متغیر x
رو درون تابع هم داریم.
وقتی یک متغیر با var
درون یک تابع تعریف میشه، حوزه این متغیر لوکال هست. یعنی فقط داخل همون تابع بهش دسترسی داریم:
function yoo() {
var x = 1;
}
yoo();
alert(x); // error: x is not defined
تعریف دوباره متغیر در var
وقتی متغیری مثلاً x
، با var
تعریف میشه، این قابلیت وجود داره که یک متغیر دیگه با var
، با همون نام، یعنی x
، تعریف بشه:
var color = "Yellow"
var color = "Navy" // ok
هویستینگ Hoisting در var
به کد زیر و به اینکه متغیر y
کجا تعریف شده دقت کنید:
alert(y); // undefined
var y = "Street"
در واقع کد بالا توی جاوااسکریپت بصورت زیر تفسیر میشه:
var y;
alert(y); // undefined
y = "Street"
همونطور که میبینیم، برای y
یک Hoisting صورت گرفت. یعنی خط ۲ توی کد اول، باعث شد که y
بره به اول حوزه خودش و با مقدار undefined
تعریف بشه.
مشکل var
به مثال زیر دقت کنین:
var greeter = "Hey Hi"
var times = 4;
if (times > 3) {
var greeter = "Hello"
}
alert(greeter) //"Hello"
وقتی توی خط سوم شرط ما برقرار میشه، متغیر greeter
دوباره تعریف و مقدارش عوض میشه. خب اگه بطور عمد این کار رو انجام داده باشیم، ظاهرا مشکلی نداره. اما وقتی متغیر greeter
از قبل توی کد ما تعریف شده باشه ولی ما از وجودش بی خبر باشیم، احتمال اینکه کد ما دچار باگ بشه زیاده. اونم باگی که ظاهراً مخفیانه هست! :)
برای همین دلایل بود کهlet
وconst
معرفی شدن.
تعریف متغیر با let
متغیرهایی که با let
تعریف میشن، دارای اسکوپ بلاکی (Block Scoped) هستن. یعنی چی؟ بلاک به قسمتی از کد گفته میشه که بین براکت { }
قرار میگیره. پس متغیرهایی که با let
توی بلاک تعریف میشن، فقط توی همون بلاک قابل دسترسی هستن، که به اصطلاح میگن Block Scoped. مثال زیر رو ببینید:
let greeting = "Say Hi"
let times = 4;
if (times > 3) {
let hello = "Say Hello"
alert(hello); // "Say Hello"
}
alert(hello) // error: hello is not defined
متغیری که توی بلاک if
تعریف شد، فقط توی همون بلاک قابل دسترسی بود و ما توی خط آخر کد بهش دسترسی نداشتیم.
تعریف مجدد متغیر با let
متغیرهای let
میتونن مقدار جدیدی بگیرن، ولی نمیتونن دوباره تعریف بشن:
let x = 24;
x = 28; // ok
کد بالا کاملاً درسته و بدون مشکل. اما کد زیر به ما ارور میده، چون داریم یک متغیری رو که قبلا با let
(یا var
) تعریف شده رو دوباره با let
تعریف میکنیم:
let x = 24;
let x = 28; // error: redeclaration of let x
// ...
var y = 45;
let y = 48; // error: redeclaration of let y
پس با توجه به اینکه متغیرهای let
بلاک اسکوپ هستن، میشه داخل اسکوپهای مختلف متغیرهایی با همون نام رو با let
تعریف کرد. بنابراین کد زیر بدون مشکل اجرا میشه:
let greeting = "Hi"
if (true) {
let greeting = "Hello"
alert(greeting); //"Hello"
}
alert(greeting); //"Hi"
با توجه به کد بالا، مشکلاتی رو که تو قسمت var
بررسی کردیم، دیگه برای let
به وجود نمیاد.
هویستینگ Hoisting در let
همونطوری که برای var
داشتیم، متغیرهای let
هم موقع تفسیر، به بالای حوزه خودشون میرن. توی عمل Hoisting، برخلاف var
که با مقدار undefined
پیادهسازی میشن، متغیرهای let
با هیچ مقداری پیادهسازی نمیشن. بنابراین وقتی متغیری رو میخوایم قبل از پیادهسازی استفاده کنیم، خطا میگیریم. درصورتی که توی var
هیچ خطایی نمیگرفتیم و فقط مقدار undefined
رو به ما تحویل میداد:
alert(f);
let f = 12;
// ReferenceError: can't access lexical declaration `f' before initialization
تعریف متغیر با const
متغیرهایی که با const
(کانست) تعریف میشن، همون ویژگیهایی رو دارن که متغیرهای let
دارن، با این تفاوت که مقدار متغیرهای const
رو دیگه نمیشه تغییر داد.
متغیرهای const
مثل let
بلاک اسکوپ هستن؛ یعنی همونطور که توی قسمت let
توضیح دادم، متغیرهای const
هم فقط توی حوزه خودشون قابل دسترسی هستن.
مقداردهی و تعریف دوباره const
متغیرهای const
وقتی تعریف و مقداردهی بشن، دیگه نمیتونن دوباره تعریف و همچنین مقداردهی بشن.
const p = 10;
p = 4;
// TypeError: invalid assignment to const `p'
const p = 12;
const p = 24;
// SyntaxError: redeclaration of const p
این قضیه درباره متغیرهایی که مقدار آبجکتی دارن فرق میکنه. وقتی یک متغیر const
یک مقدار آبجکتی داره، آیتمهای موجود در آبجکت رو میشه بدون هیچ مشکلی تغییر داد:
const person = {
name: "John",
lastname: "Doe"
}
person.name = "Davood"
console.log(person); // { name: "Davood", lastname: "Doe" }
این نکته رو در نظر داشته باشید که ما نمیتونیم کل آبجکت رو جایگزین کنیم. کد زیر به ما خطا برمیگردونه:
const person = {
name: "John",
lastname: "Doe"
}
const person = {
name: "David",
lastname: "Beckham"
}
// SyntaxError: redeclaration of const person
متغیرهای const
همیشه باید با یک مقدار پیادهسازی بشن:
const u;
// SyntaxError: missing = in const declaration
هویستینگ Hoisting در const
هویستینگ Hoisting در const
درست مثل let
هست. یعنی متغیرها به بالای حوزه خودشون میرن ولی پیادهسازی نمیشن. پس اگه متغیری رو قبل از اینکه پیادهسازی کنیم صدا بزنیم، خطا میگیریم.
خلاصه
- متغیرهای var یا دارای حوزه سراسری هستن، یا حوزه تابعی. متغیرهای let و const دارای حوزه بلاکی هستن (Block Scoped).
- متغیرهای var میتونن دوباره با var تعریف و همچنین مقداردهی بشن. متغیرهای let دوباره نمیتونن تعریف بشن، ولی میتونن دوباره مقداردهی بشن. متغیرهای const، نه میتونن دوباره تعریف و نه دوباره مقداردهی بشن.
- متغیرهای var و let و const موقع عملیات Hoisting، بالای حوزه خودشون میرن، به طوری که متغیرهای var با مقدار undefined پیادهسازی میشن. درصورتی که توی let و const، متغیرها با هیچ مقداری پیادهسازی نمیشن.
- وقتی متغیرهای var و let رو تعریف میکنیم، میتونیم بهشون مقدار ندیم و بعداً این کار رو انجام بدیم. ولی متغیرهای const رو همیشه باید با مقدار، پیادهسازی کنیم.
خب دوستان امیدوارم از این مقاله استفاده کرده باشین. اگه سوال یا نظری دارید حتما توی قسمت نظرات از من بپرسید.
منبع:
مطلبی دیگر از این انتشارات
معرفی Umee، یک پلتفرم DeFi و بررسی ارز Umee
مطلبی دیگر از این انتشارات
سالیدیتی از ایده تا عمل در یک هفته
مطلبی دیگر از این انتشارات
چند سناریوی احتمالی برای قیمت بیت کوین