من میدانم که هیچ نمیدانم.
بررسی (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 رو همیشه باید با مقدار، پیادهسازی کنیم.
خب دوستان امیدوارم از این مقاله استفاده کرده باشین. اگه سوال یا نظری دارید حتما توی قسمت نظرات از من بپرسید.
منبع:
مطلبی دیگر از این انتشارات
۵ مجموعه NFT برتر سال 2022 برای سرمایهگذاری
مطلبی دیگر از این انتشارات
متاورس مارکتینگ چیست؟
مطلبی دیگر از این انتشارات
متاورس چیست ؟