راهنمای عملی ES6: درآمدی بر کلیدواژه‌های let و const

راهنمای عملی ES6: درآمدی بر کلیدواژه‌های let و const

در این آموزش به معرفی دو کلیدواژهٔ let و const پرداخته‌ایم. این دو کلیدواژه،‌ با انتشار ES6 به جاوااسکریپت اضافه شده و راهی برای تعریف متغیر‌ها و کانستنت‌های اصطلاحاً Block-scoped را در این زبان فراهم آورده‌اند (Block-scope حالتی است که متغیر یا کانستنت تنها برای استفاده در یک Block تعریف می‌شود و Block هم تمام کدهای بین دو علامت } و { را شامل می‌شود).

آشنایی با let در ES6
تا قبل از انتشار ES6،‌ در جاوااسکریپت متغیرها و کانستنت‌ها تنها با دو دامنه (Scope) تعریف می‌شدند که عبارتند از:
- Function Scope
- Global Scope

بنابراین،‌ امکان تعریف متغیر‌ها و کانستنت‌ها به صورت Block-scope وجود نداشت که این موضوع سبب سردرگمی و ناامیدی دولوپرهایی شده بود که از سایر زبان‌هایی مانند سی، سی‌پلاس‌پلاس و یا جاوا آمده‌ بودند. برای درک بهتر این موضوع، به مثال زیر دقت کنید:

function foo() {
  var par = 1;
  if (par >= 0) {
    var bar = 2;
    console.log(par); // prints 1
    console.log(bar); // prints 2
  }
  console.log(par); // prints 1
  console.log(bar); // prints 2
}
foo();

پس از اجرا شدن این کد، نتایج زیر در کنسول نمایش داده می‌شود:

1
2
1
2

از دیدگاه اغلب دولوپرهایی که از زبان‌های فوق‌الذکر آمده‌اند، خارج از بلوک if، امکان دسترسی به متغیر bar وجود ندارد. به عنوان مثال، اجرای معادل این کد در زبان C منجر به ایجاد ارور bar' undeclared at line' خواهد شد که به استفاده از متغیر bar خارج از بلوک if اشاره دارد (البته در ES5 این دیدگاه درست بود و چنین مشکلی وجود داشت).

در ES6 این وضعیت تغییر کرده و امکان تعریف متغیرهای به اصطلاح Block-scoped فراهم شد. اعضای سازمان ECMA می‌دانستند که برای حل این مشکل نمی‌توانند رفتار کلیدواژهٔ var را تغییر دهند زیرا در این صورت کدهایی که پیش از این نوشته شده بودند،‌ دچار مشکل می‌شدند؛ بنابراین تصمیم گرفتند تا کلیدواژهٔ‌ جدیدی به نام let را معرفی کنند که از این کلیدواژه می‌توان برای ایجاد متغیرهایی استفاده کرد که دامنهٔ استفادهٔ آن‌ها به بلوکی که در آن تعریف شده‌اند،‌ محدود می‌شود.

در همین راستا، لازم به ذکر است که اگر قبل از تعریف متغیر با استفاده از کلیدواژهٔ‌ let در بلوکی به آن رفرنس دهید، با ReferenceError مواجه خواهید شد. اما این در عمل به چه معنا است و آیا فقط برای مبتدی‌ها خوب است؟ البته که خیر.

var nodes = document.getElementsByTagName('button');
for (var i = 0; i < nodes.length; i++) {
  nodes[i].addEventListener('click', function() {
    console.log('You clicked element #' + i);
  });
}

در مثال فوق می‌توانید یکی از رایج‌ترین مسائل مربوط به تعریف متغیر، Scope و Event Handler آن را ببینید. این مسئله در ES6 می‌تواند به سادگی با تعریف متغیر i در حلقهٔ‌ for،‌ با استفاده از کلیدواژهٔ‌ let حل شود. به کد زیر توجه کنید:

var nodes = document.getElementsByTagName('button');
for (let i = 0; i < nodes.length; i++) {
  nodes[i].addEventListener('click', function() {
    console.log('You clicked element #' + i);
  });
}

عباراتی که با let نوشته می‌شوند،‌ در Node و همهٔ مرورگرهای امروزی پشتیبانی می‌شوند (البته نکات ریزی در مورد این عبارات در Internet Explorer 11 وجود دارد).

آشنایی با const در ES6
کلیدواژهٔ const نیاز دولوپرها برای استفاده از یک مقدار ثابت و بدون تغییر با یک نام مستعار را برطرف نموده است. به عبارت ساده‌تر،‌ این کلیدواژه برای تعریف کانستنت‌ها (ثابت‌ها) مورد استفاده قرار می‌گیرد. به عنوان مثال، هنگامی که با فرمول‌های ریاضیاتی کار می‌کنید، ممکن است به ایجاد یک اصطلاحاً Math Object نیاز پیدا کنید. درون این آبجکت ممکن است بخواهید مقادیری مانند π و e را با نام مستعارشان به کار ببرید. کلیدواژهٔ‌ const در رسیدن به این هدف شما را یاری می‌کند. در واقع، با استفاده از این کلیدواژه می‌توانید کانستنتی تعریف کنید که دامنهٔ Global یا Local داشته باشد.

از نظر دامنهٔ‌ کاربرد (Scope)،‌ کانستنت‌هایی که با کلیدواژهٔ const تعریف می‌شوند از همان قوانین حاکم بر متغیرها پیروی می‌کنند به جز اینکه مقدار آن‌ها قابل‌تغییر نیست. همچنین، آن‌ها با متغیرهایی که با کلیدواژهٔ‌ let تعریف می‌شوند نیز یک وجه اشتراک دارند و آن هم اینکه به جای Function-scoped بودن، Block-scoped هستند.

همچنین لازم به ذکر است که اگر قبل از تعریف یک کانستنت آن را در جای دیگری مورد استفاده قرار دهید، با ReferenceError مواجه خواهید شد. علاوه بر این، اگر بخواهید مقدار متغیری که با کلیدواژهٔ‌ const تعریف شده است را تغییر دهید، با TypeError مواجه می‌شوید.

البته توجه داشته باشید که هرچند کلیدواژهٔ const یک ساختار تغییرناپذیر (Immutable) را ایجاد می‌کند، اما چنان که در کد زیر نشان داده شده است،‌ عملاً نشان‌دهندهٔ تغییرناپذیری و ثبات نیست:

const foo = {};
foo.bar = 42;
console.log(foo.bar);
// → 42

اگر می‌خواهید آبجکتی که ایجاد می‌کنید واقعاً تغییرناپذیر باشد،‌ باید از ()Object.freeze استفاده کنید.

مشابه آنچه که در مورد let گفته شد، عبارات نوشته شده با کلید واژهٔ‌ const نیز در Node و همهٔ‌ مرورگرهای امروزی پشتیبانی می شوند (البته در این مورد نیز نکاتی در مورد Internet Explorer 11 وجود دارد که باید مورد توجه قرار گیرد). نمونه‌ای از کاربرد کلیدواژهٔ const را در کد زیر مشاهده می‌کنید:

'use strict';

function foo() {
  const con1 = 3.141;
  if (con1 > 3) {
    const con2 = 1.414;
    console.log(con1); // prints 3.141
    console.log(con2); // prints 1.414
  }
  console.log(con1); // prints 3.141
  try {
    console.log(con2);
  } catch(ex) {
    console.log('Cannot access con2 outside its block');
  }
}
foo();

در این آموزش در مورد دو کلیدواژهٔ let و const توضیحاتی ارائه شد. این دو کلیدواژه که در ES6 معرفی شده‌اند، روش جدیدی برای تعریف متغیرها را در اختیار دولوپرها قرار می‌دهند. هرچند کلیدواژهٔ‌ var در آیندهٔ‌ نزدیک (و البته شاید هیچ وقت) حذف نشود، اما به منظور کاهش ارورهای کد، توصیه بر این است که در صورت امکان به جای کلیدواژهٔ‌ var، از کلیدواژه‌های let و const استفاده شود.

منبع


رائفه خلیلی