از سه کلمه ی کلیدی let, const و var برای تعریف متغیر در جاوااسکریپت استفاده می شود.
مقدار دهی اولیه(Initializer):
متغیر let , var میتونن مقدار اولیه داشته باشند یا نداشته باشند ولی const حتما باید مقدار دهی اولیه شود در غیر اینصورت با SyntaxError مواجه می شویم.
مقدار دهی دوباره(Reassign):
بعد از اینکه متغیری و با var و let تعریف کردیم میتوانیم بعدا نیز مقدار جدیدی با آن اساین کنیم. اگر متغیری با const تعریف شده باشه قابل مقدار دهی دوباره نیست و با TypeError مواجه می شویم.
تعریف مجدد(Redeclaring):
متغیرهایی که با const و let در جاوا اسکریپت تعریف شده اند از لحاظ Redeclaring شبیه هم هستند چون نمیتوان آنها را مجددا با همان نام تکراری تعریف کرد. اما var در جاوا اسکریپت از لحاظ Redeclaring مشکلی ندارد و میتوان هرچند بار که میخواهیم آن را با همان نام مجددا تعریف کنیم.
استفاده از حافظه(RAM):
در مورد let و const در جاوا اسکریپت، Global Object ذخیره نمیکنند که باعث کاهش مصرف حافظه میشود. اما var در جاوا اسکریپت، یک Global Object در حافظه ذخیره میکند و رم بیشتری نسبت به let و const اشغال میکند.
بالا بردن(hoisting):
پنجمین تفاوت var و let و const در جاوا اسکریپت، در Hoisting است. Hoisting در لغت به معنی بالا بردن است؛ در اصطلاح برنامه نویسی نیز Hoisting در جاوا اسکریپت به پدیدهای اشاره دارد که در هنگام اجرای کد، تعریف متغیرها و تابعها به بالای بلوک کدی که در آن قرار دارند منتقل میشوند. به این ترتیب، میتوانید از متغیرها و توابع قبل از تعریف آنها استفاده کنید.
به طور معمول، در زبانهای برنامه نویسی، باید متغیرها و توابع را قبل از استفاده از آنها، تعریف کنید (اول تعریف کنید و سپس استفاده کنید). اما در جاوا اسکریپت، به دلیل وجود Hoisting، میتوانید از متغیرها و توابع قبل از تعریف آنها استفاده کنید (اول استفاده کنید و سپس تعریف کنید). var قابلیت hoisting دارد ولی let و const چنین قابلیتی ندارند و اگر قبل از تعریف متغیر با let از آن استفاده کنیم با RefrenceError مواجه می شویم.
console.log(x); // undefined
var x = 5;
console.log(x); // Uncaught ReferenceError: Cannot access 'x' before initialization (TDZ)
let x = 5;
console.log(x); // Uncaught ReferenceError: Cannot access 'x' before initialization (TDZ)
const x = 5;
در کلمه کلیدی const نیز مانند let، قابلیت Hoisting وجود ندارد.
تلاش برای دسترسی به متغیرها قبل از تعریف آنها باعث خطا در اجرا برای let و const میشود، که به آن Temporal Dead Zone (TDZ) یا «منطقه مرده موقت» میگوییم. TDZ به محدودهای اشاره دارد که در آن متغیرهایی که با استفاده از let و const تعریف شدهاند، اما هنوز قابل دسترسی نیستند. به عبارت دیگر، از زمان شروع اجرا تا اولین لحظه تعریف و مقداردهی اولیه، متغیر در TDZ قرار دارد و تلاش برای دسترسی به آن باعث ایجاد خطا (ReferenceError) میشود.
محدوده (scope):
محدوده، یعنی جایی که یک متغیر قابل دسترسی است.
بهطور کلی 3 اسکوپ در جاوا اسکریپت داریم:
متغیر var یک فانکشن اسکوپ است و فقط داخل فانکشن قابل دسترسی است. متغیر let و ثابت const نیز بلاک اسکوپ هستند و فقط داخل بلاک قابل دسترسی هستند. اما نکتهای که باید بدانید این است که اگر متغیر var داخل بلاک باشد، به دلیل بلاک اسکوپ نبودن، میتوان از بیرون به آن دسترسی پیدا کرد. اما اگر متغیر let و ثابت const داخل فانکشن قرار بگیرند، با اینکه بلاک اسکوپ هستند، باز هم از بیرون تابع نمیتوان به آنها دسترسی پیدا کرد. یعنی هم بلاک اسکوپ و هم فانکشن اسکوپ را قبول میکنند.
مشکل var این است که اگر متغیر message از قبل داخل کدهای ما تعریف شده باشد ولی از وجود آن بیخبر باشیم، احتمال اینکه کد ما دچار باگ شود زیاد است. چون مقدار متغیر جدید، متغیر قبلی را تغییر میدهد. اما در let و const به دلیل Block Scope بودن، وقتی داخل بلاک if قرار بگیرند، داخل همان بلاک قابل دسترسی هستند و مقدار متغیر بیرونی را تغییر نخواهند داد. حافظه ی زیادی را به نسبت let و const اشغال می کند.
کلمات کلیدی let و const در اکما اسکریپت ۶ اضافه شده اند.
جمع بندی:
متغیر var منسوخ نشده است و در جاوا اسکریپت میتوانید از آن استفاده کنید اما یک متغیر غیراستاندارد است و مشکلات زیادی را به بار میآورد. پس بجای استفاده از متغیر var، همیشه از متغیر let و const استفاده کنید.