بررسی (let - var - const) در جاوااسکریپت

درود دوستان. توی این پست روش‌های مختلف ساخت متغیرها رو بطور مفصل با هم بررسی می‌کنیم.کلی ویژگی جالب و جدید توسط ES6 به جاوااسکریپت اضافه شده و این زبان رو محبوب تر از همیشه کرده. در کنار var که تنها روش موجود در جاوااسکریپت بود، ES6 دوتا روش جدید برای ساخت متغیرها معرفی کرده که let و const هستن. اگه تا الان از var استفاده می‌کردین و کاربرد let و const رو نمیدونین، شاید از خودتون بپرسین من که تا الان از var استفاده می‌کردم و هیچ مشکلی وجود نداشت، پس چرا باید از let استفاده کنم؟ بهتره که این مقاله رو خوب بخونین؛ چون پیشنهاد میشه کم کم با var خداحافظی کنین.قبل از شروع بهتره با چند تا تعریف آشنا بشیم.۱. اسکوپ (Scope) یا حوزهاسکوپ (Scope) یا حوزه، به جاهایی گفته میشه که متغیرها قابل دسترسی و استفاده هستنیعنی یک متغیر توی چه جاهایی قابل دسترسی هست. مثلا توی تابع یا کلاس.متغیرهای سراسری دارای حوزه Global هستن (Global Scope). یعنی همه جا در دسترس هستن. https://virgool.io/Solidity/what-is-scope-in-javascript-efseqijfobdh ۲. هویستینگ (Hoisting)این واژه توی زبان پارسی یعنی بالا بردن یه چیزی.هویستینگ Hoisting توی جاوااسکریپت مکانیزمی هست که باعث میشه قبل از اجرای برنامه، متغیرها و توابع، به بالاترین سطح حوزه خودشون جابجا بشن.با Hoisting توی هر آیتم var و let و const بیشتر آشنا می‌شیم. حالا هر ۳ مورد رو می‌تونیم بهتر بررسی کنیم. https://virgool.io/Solidity/what-is-hoisting-in-javascript-eljqu39tvcp9 تعریف متغیر با varقبل از اینکه ES6 معرفی بشه، تنها راه موجود ساخت متغیرها تو جاوااسکریپت var بود. استفاده از var باعث به وجود اومدن مشکلاتی می‌شد و به همین دلیل به وجود اومدن یک راه جدید رو الزامی کرد. قبل از اینکه درباره این مشکلات صحبت کنیم، بیاین درباره var بیشتر بدونیم.متغیرهایی که با var تعریف میشن، می‌تونن یا حوزه سراسری داشته باشن یا لوکال (محلی). یک متغیر وقت بیرون از یک تابع تعریف شده باشه حوزه سراسری داره. یعنی وقتی یک متغیر با var بیرون از یک تابع تعریف شده باشه، توی همه جای برنامه در دسترس هست. حتی درون تابع:var x = &quotThis is a book&quot 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 = &quotYellow&quot var color = &quotNavy&quot // okهویستینگ Hoisting در varبه کد زیر و به اینکه متغیر y کجا تعریف شده دقت کنید:alert(y); // undefined var y = &quotStreet&quotدر واقع کد بالا توی جاوااسکریپت بصورت زیر تفسیر میشه:var y; alert(y); // undefined y = &quotStreet&quotهمونطور که می‌بینیم، برای y یک Hoisting صورت گرفت. یعنی خط ۲ توی کد اول، باعث شد که y بره به اول حوزه خودش و با مقدار undefined تعریف بشه.مشکل varبه مثال زیر دقت کنین:var greeter = &quotHey Hi&quot var times = 4; if (times > 3) { var greeter = &quotHello&quot } alert(greeter) //&quotHello&quotوقتی توی خط سوم شرط ما برقرار میشه، متغیر greeter دوباره تعریف و مقدارش عوض میشه. خب اگه بطور عمد این کار رو انجام داده باشیم، ظاهرا مشکلی نداره. اما وقتی متغیر greeter از قبل توی کد ما تعریف شده باشه ولی ما از وجودش بی خبر باشیم، احتمال اینکه کد ما دچار باگ بشه زیاده. اونم باگی که ظاهراً مخفیانه هست! :)برای همین دلایل بود که let و const معرفی شدن.تعریف متغیر با letمتغیرهایی که با let تعریف میشن، دارای اسکوپ بلاکی (Block Scoped) هستن. یعنی چی؟ بلاک به قسمتی از کد گفته میشه که بین براکت { } قرار میگیره. پس متغیرهایی که با let توی بلاک تعریف میشن، فقط توی همون بلاک قابل دسترسی هستن، که به اصطلاح میگن Block Scoped. مثال زیر رو ببینید:let greeting = &quotSay Hi&quot let times = 4; if (times > 3) { let hello = &quotSay Hello&quot alert(hello); // &quotSay Hello&quot } 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 = &quotHi&quot if (true) { let greeting = &quotHello&quot alert(greeting); //&quotHello&quot } alert(greeting); //&quotHi&quotبا توجه به کد بالا، مشکلاتی رو که تو قسمت 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: &quotJohn&quot, lastname: &quotDoe&quot } person.name = &quotDavood&quot console.log(person); // { name: &quotDavood&quot, lastname: &quotDoe&quot }این نکته رو در نظر داشته باشید که ما نمی‌تونیم کل آبجکت رو جایگزین کنیم. کد زیر به ما خطا برمی‌گردونه:const person = { name: &quotJohn&quot, lastname: &quotDoe&quot } const person = { name: &quotDavid&quot, lastname: &quotBeckham&quot } // 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 رو همیشه باید با مقدار، پیاده‌سازی کنیم.خب دوستان امیدوارم از این مقاله استفاده کرده باشین. اگه سوال یا نظری دارید حتما توی قسمت نظرات از من بپرسید.منبع:https://sarahchima.com/blog/var-let-const-difference