با سلام خدمت شما خوانندگان گرامی، در سال 2015 دو کلیدواژه ی مهم به نام های let
و const
به جاوا اسکریپت معرفی شد که کارشان تعریف Block Scope در متغیرها بود. قبل از ECMAScript 2015 تنها دو نوع scope در جاوا اسکریپت داشتیم: Global Scope و Function Scope. امروز قصد داریم در رابطه با اولین مورد، یعنی let
، صحبت کنیم. ابتدا باید نگاهی به این دو scope اولیه داشته باشیم...
متغیرهایی که به صورت سراسری یا Global (به عبارتی خارج از توابع) تعریف شوند، دارای Global scope یا دامنه ی سراسری هستند:
<!DOCTYPE html> <html> <body> <h2>JavaScript Scope</h2> <p>A GLOBAL variable can be accessed from any script or function.</p> <p id="demo"></p> <script> var carName = "Volvo"; myFunction(); function myFunction() { document.getElementById("demo").innerHTML = "I can display " + carName; } </script> </body> </html>
خروجی این کد عبارت "I can display Volvo" خواهد بود.
ما می توانیم از هر جایی که بخواهیم به متغیر های سراسری یا Global دسترسی پیدا کنیم.
توابعی که به صورت محلی (Local) تعریف شوند (به عبارتی داخل تابع باشند) دارای Function Scope هستند:
<!DOCTYPE html> <html> <body> <h2>JavaScript Scope</h2> <p>Outside myFunction() carName is undefined.</p> <p id="demo1"></p> <p id="demo2"></p> <script> myFunction(); function myFunction() { var carName = "Volvo"; document.getElementById("demo1").innerHTML = typeof carName + " " + carName; } document.getElementById("demo2").innerHTML = typeof carName; </script> </body> </html>
خروجی این تابع به این صورت خواهد بود:
string Volvo
undefined
متغیر های محلی تنها از داخل خودِ تابع در دسترس هستند و همانطور که در مثال بالا می بینید اگر آن ها را از بیرون تابع صدا بزنیم به مقدار undefined برمیخوریم.
تا اینجا متوجه شدیم که اگر متغیری با var
تعریف شود نمی تواند Block Scope داشته باشد. حال متغیر هایی که داخل بلوکه ای تعریف شوند (یعنی داخل علامت های { } باشند) از بیرون هم قابل دسترسی هستند. مثال:
{ var x = 2; } // باز هم می توان از اینجا به ایکس دسترسی داشت
قبل از ES2015 چنین چیزی (Block Scope به معنی دامنه ی بلوکه ای) در جاوا اسکریپت وجود نداشت اما متغیرهایی که با استفاده از let
تعریف شوند دارای Block Scope هستند بنابراین اگر داخل بلوکه { } تعریف شوند، دیگر از خارج قابل دسترسی نیستند:
{ let x = 2; } // دیگر از اینجا نمی شود به ایکس دسترسی داشت چرا که دامنه ی خاصی دارد
در مثال بالا scope داریم و به همین علت تنها داخل آن scope می توانیم از آن استفاده کنیم.
اگر متغیر ها را با استفاده از var
تعریف کنیم و بخواهیم دوباره آن را تعریف کنیم به مشکل برمیخوریم. به مثال زیر دقت کنید:
<!DOCTYPE html> <html> <body> <h2>Declaring a Variable Using var</h2> <p id="demo"></p> <script> var x = 10; // مقدار ایکس در اینجا 10 است { var x = 2; // مقدار ایکس در اینجا 2 است } // مقدار ایکس در اینجا 2 است document.getElementById("demo").innerHTML = x; </script> </body> </html>
خروجی این کد عدد 2 خواهد بود.
احتمالا متوجه مشکل شده اید؛ از آنجا که var ها scope بلوکه ای ایجاد نمی کنند، اگر متغیر را در بلوکی دوباره declare کنید از آن به بعد مقدارش تغییر می کند. راه حل چیست؟
شما می توانید از let
استفاده کنید تا متغیرهایتان دارای scope شوند:
<!DOCTYPE html> <html> <body> <h2>Declaring a Variable Using let</h2> <p id="demo"></p> <script> var x = 10; // مقدار ایکس در اینجا 10 است { let x = 2; // مقدار ایکس در اینجا 2 است } // مقدار ایکس در اینجا 10 است document.getElementById("demo").innerHTML = x; </script> </body> </html>
خروجی این کد عدد 10 می باشد.
پشتیبانی از کلیدواژه ی let
به شرح زیر است:
Opera 36 | Safari 11 | Firefox 44 | IE / Edge 12 | Chrome 49 |
Mar, 2016 | Sep, 2017 | Jan, 2015 | Jul, 2015 | Mar, 2016 |
نسخه هایی که در جدول بالا آمده است، اولین نسخه ای است که از کلیدواژه ی let
پشتیبانی می کند بنابراین Internet Explorer 11 از آن پشتیبانی نمی کند.
اگر در یک حلقه از var
استفاده کنید:
var i = 5; for (var i = 0; i < 10; i++) { // some statements } // 10 است i مقدار
اگر از let
استفاده کنید:
let i = 5; for (let i = 0; i < 10; i++) { // some statements } // 5 است i مقدار
توضیح:
var
استفاده کردیم بنابراین متغیری که داخل تابع تعریف کرده ایم دوباره خارج از تابع تعریف می شود.let
استفاده کرده ایم بنابراین متغیری که داخل تابع تعریف شده است دوباره خارج است تابع تعریف نمی شود.استفاده از var
یا let
داخل توابع هیچ تغییری ایجاد نمی کند و همچنان Function Scope برقرار خواهد بود. دو کد زیر از نظر scope هیچ تفاوتی با هم ندارند:
function myFunction() { var carName = "Volvo"; // Function Scope }
function myFunction() { let carName = "Volvo"; // Function Scope }
این نکته برای Global Scope نیز صادق است و دو کد زیر یک Scope را دارند:
var x = 2; // Global scope
let x = 2; // Global scope
همانطور که می دانید scope سراسری یا global در جاوا اسکریپت، همان محیط اجرای جاوا اسکریپت است که در HTML می شود همان شیء window. بنابراین متغیرهای سراسری که با var
تعریف شوند جزئی از شیء window خواهند بود. به طور مثال هر دو کد زیر یکسان هستند:
var carName = "Volvo"; document.getElementById("demo").innerHTML = "I can display " + carName;
var carName = "Volvo"; document.getElementById("demo").innerHTML = "I can display " + window.carName;
خروجی هر دو کد عبارت "I can display Volvo" خواهد بود.
قانون اول: اجازه دارید متغیر هایی را که با var
تعریف شده اند، در هر کجا از برنامه تان دوباره declare یا تعریف کنید:
var x = 2; var x = 3;
قانون دوم: تعریف دوباره ی متغیر های var
با کلیدواژه ی let
(اگر در یک scope باشند) مجاز نیست و تنها اولی محاسبه می شود:
var x = 2; // مجاز let x = 3; // غیر مجاز
همچنین تعریف دوباره ی متغیر های let
با let
در یک scope مجاز نمی باشد:
let x = 2; // مجاز let x = 3; // غیر مجاز
اما اگر در scope دیگر باشند، مشکلی نیست:
let x = 2; // مجاز { let x = 3; // مجاز }
این قانون برای جایگزینی متغیر های let
با var
نیز صادق است.
در جلسات قبلی در رابطه با مبحث Hoisting صحبت کرده ایم. متغیر هایی که با var
تعریف شوند Hoist می شوند اما متغیر های let
سر جایشان باقی می مانند و Hoist نمی شوند. بنابراین اگر قبل از تعریف متغیر های let
، از آن ها استفاده کنید با خطای ReferenceError
مواجه می شوید.
امیدوارم از این قسمت لذت برده باشید. در قسمت بعد به سراغ مبحث const
خواهیم رفت.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.