کلمه let در جاوااسکریپت چیست ؟ تعریف متغیر با کلمه let
زمان مطالعه:6 دقیقه

کلمه let در جاوااسکریپت چیست ؟ تعریف متغیر با کلمه let

قبل تر بصورت مفصل درمورد متغیرها در جاوااسکریپت صحبت کردیم و امروز در این مقاله میخواهیم نگاهی اختصاصی و ریزبینانه تر به تعریف متغیر با کلمه کلیدی let داشته باشیم.

تعریف متغیر با استفاده از کلمه let یک متغیر block-scoped local variable ( block scope محلی ) تعریف میکنه و موقع تعریف کردن ما میتونیم بصورت اختیاری برای متغیر مدنظر مقداری را در نظر بگیریم و یا اینکه بدون مقدار اون متغیر رو تعریف کنیم.

let x = 1;

if (x === 1) {
  let x = 2;

  console.log(x);
  // خروجی : 2
}

console.log(x);
// خروجی : 1

سینتکس تعریف متغیر با کلمه let

let name1;
let name1 = value1;
let name1 = value1, name2 = value2;
let name1, name2 = value2;
let name1 = value1, name2, /* …, */ nameN = valueN;

همچنین امکان Destructuring هم برای متغیرهایی که مقدارشون برابر با یک object هست هم وجود داره، مثل نمونه زیر:

let foo = {
  bar:10,
  baz:12,
}

let { bar } = foo; // where foo = { bar:10, baz:12 };
/* ba inkar engar darim yek variable jadid ba name bar injad mikonim */

let به شما اجازه میده تا متغیرهایی با دامنه محدود ( block-scope ) یا محدود به دامنه قطعه کدی که در اون استفاده شده ایجاد کنید ( مثلا محدود به یک function ) و این بر خلاف کلمه کلیدی var هست که یک متغیر را به صورت سراسری ( globaly ) یا محلی به کل یک function بدون توجه به محدوده بلوک ایجاد میکنه هستش. تفاوت دیگر بین var و let این هست که متغیرهای که با let تعریف میشن فقط بعد از جایی که تعریف شدن قابل دسترس هستند ( یعنی اگر در خط 10 کد ما تعریف شدن ما نمیتونیم در خط 9 از اونها استفاده کنیم ) و به این دلیل ما let رو non-hoisted میشناسیم ( یعنی  hoist نمیشن و برخلاف var  به بالای scope منتقل نمیشن )

دقیقا همانند const متغیرهایی که با let بصورت globaly ( در بالاترین سطح scope ) تعریف میشوند هم هیچگونه property آبجکت window ایجاد نمیکنند.

برخلاف var شما نمیتوانید یک متغیری که با کلمه let ایجاد شده است را بصورت تنها در بدنه یک block داشته باشید و این بخاطر این هست که هیچ راهی برای دسترسی به اون متغیر وجود نداره، به مثال زیر توجه کنید:

if (true) let a = 1; 
// SyntaxError: Lexical declaration cannot appear in a single-statement context

مثال هایی از تعریف متغیر با کلمه let

قوانین مربوط به scope

متغیرهایی که با کلمه let ایجاد میشن scope خودشون رو در بلوکی که توش تعریف شدن دارن و از اینرو let با var مشابه است اما یک تفاوتی وجود داره و اونهم این هست که scope متغیرهای ایجاد شده با کلمه var کل فانکشنی هست که در اون محصور شدن، به مثال زیر توجه کنید:

function varTest() {
  var x = 1;
  {
    var x = 2; // same variable!
    console.log(x); // 2
  }
  console.log(x); // 2
}

function letTest() {
  let x = 1;
  {
    let x = 2; // different variable
    console.log(x); // 2
  }
  console.log(x); // 1
}

در بالاترین سطح scope، متغیرهایی که با کلمه let ایجاد میشوند برخلاف var هیچگونه property را در global object ایجاد نمیکنند:

var x = "global";
let y = "global";
console.log(this.x); // "global"
console.log(this.y); // undefined

همجنین داخل یک block اگر متغیری را با let تعریف کنیم، اون متغیر محدود به scope همان block خواهد بود و در اینحا ما رفتار متفاوتی رو بین متغیرهای let با متغیرهای var که scope اونها مربوط به فانکشنی هستند که در اون تعریف شدن:

var a = 1;
var b = 2;

{
  var a = 11; // global-scope
  let b = 22; // scope mahdood be hamin block hast

  console.log(a); // 11
  console.log(b); // 22
}

console.log(a); // 11
console.log(b); // 2

تعریف مجدد

تعریف مجدد متغیرهایی که در scope همان فانکشنی که قبلا درآن تعریف شدن و یا block scope باعث ایجاد ارور میشه:

if (x) {
  let foo;
  let foo; // SyntaxError thrown.
}

همچنین ممکنه با ارور بالا در یک switch statement هم مواجه بشید چراکه در اونجا هم فقط یک block وجود داره:

let x = 1;

switch (x) {
  case 0:
    let foo;
    break;
  case 1:
    let foo; // SyntaxError for redeclaration.
    break;
}

اما یک block تو در تو داخل case یک محیط block scope جدید ایجاد میکنه و از اروری که در بالا ایجاد شد جلوگیری میکنه:

let x = 1;

switch (x) {
  case 0: {
    let foo;
    break;
  }
  case 1: {
    let foo;
    break;
  }
}

منطقه مرده زمانی ( Temporal dead zone یا TDZ )

یک متغیر تعریف شده با کلمه let یا const اصطلاحا گفته میشه که از ابتدای block تا زمانیکه اجرای کد به محل تعریف شدن این متغیرها نرسیده، اونها در منطقه مرده زمانی یا TDZ هستند و تا زمانیکه اون متغیر داخل TDZ هست هر تلاشی برای دسترسی به اون متغیر باعث ایجاد ارور referenceError خواهد شد و زمانیکه اجرای کد به محل تعریف شدن این متغیر میرسه درصورتی که این متغیر مقداردهی اولیه نشده باشه بصورت پیشفرض مقدار اون برابر با undefined خواهد بود.

یک تفاوت دیگر بین var و let این هست که حتی قبل از محل تعریف شدن متغیرهای var هم ما میتونیم از اونها استفاده کنیم و برخلاف متغیرهای let اروری ایجاد نخواهد شد ( هرچند که مقدار اونها قبل از رسیدن به محل تعریف شدن و مقداردهی شدنشون برابر با undefined خواهد بود ) به مثال زیر توجه کنید:

{
  // TDZ starts at beginning of scope
  console.log(bar); // undefined
  console.log(foo); // ReferenceError
  var bar = 1;
  let foo = 2; // End of TDZ (for foo)
}

این نکته را به خاطر داشته باشید که ما از اصطلاح زمان استفاده میکنیم نه جایی که کد نوشته شده. یعنی مواقعی هم هست که ما متغیری را قبل از ایجاد شدنش استفاده میکنیم اما اون کد درست کار میکنه و اروری ایجاد نمیشه و این خود بیانگر این هست که اصطلاح TDZ مربوط به زمان اجرای کد هست و نه جایگاهی که کد نوشته شده به مثال زیر توجه کنید، در کد زیر ما یک فانکشن داریم که توی اون فانکشن از یک متغیری که هنوز تعریف نشده استفاده کردیم ولی هنوز اون کد رو اجرا نکردیم و فانکشن نوشته شده رو صدا نزدیم، بنابر این اروری رو دریافت نمیکنیم چون هنوز زمان اجرای کد نوشته شده نرسیده و پس از تعریف شدن متغیر فانکشن مدنظرمون رو صدا میزنیم و کد ما به خوبی و خوشی کار میکنه:

{
  // shorooe TDZ
  const func = () => console.log(letVar); // OK

  // agar inja va ghabl az tarife letVar function ra seda bezanim error migirim

  let letVar = 3; // TDZ inja tamoom mishe
  func(); // code ro dige kharej az TDZ seda zadim va hame chiz ok hastesh
}

let

#

variables

#

https://vaspar.io/blog/let-keyword-in-javascript

اشتراک گذاری:

نظرات

500

/

0