بررسی پارامترهای Rest در جاوااسکریپت

سلام دوستان. توی این قسمت می‌خوایم پارامتر رست (Rest) رو بررسی کنیم که به ما کمک می‌کنه کدهایی با حجم کمتر، خواناتر و با قابلیت توسعه بیشتری داشته باشیم.

توی این قسمت موارد زیر رو یاد می‌گیریم:

  • مشکل کجاست
  • پارامتر رست (Rest) چیه
  • قوانین استفاده از پارامتر رست
  • تفاوت پارامتر رست و آبجکت arguments




مشکل کجاست؟

فرض کنیم تابعی داریم که ۲ عدد رو با هم جمع می‌کنه:

const add = (a, b) => a + b;

حالا می‌خوایم کاری کنیم که این تابع ۳ عدد رو با هم جمع کنه. شاید چیزی که به ذهنمون برسه اینه که بریم تابع رو دستکاری و یک پارامتر دیگه تعریف کنیم:

const add = (a, b, c) => a + b + c;

اگه توی شرایطی بخوایم همزمان ۲ عدد، ۴ عدد، ۵ عدد و ... رو با هم جمع کنیم چطور؟ یا باید برای هر جمع یک تابع اختصاصی تعریف کنیم یا اینکه کاری کنیم تابع تعداد ورودی‌های دلخواهی بگیره. مورد دوم قطعاً منطقی‌تر به حساب میاد. توی جاوااسکریپت پارامتر رست Rest به ما کمک می‌کنه که چنین قابلیتی داشته باشیم ?




پارامتر رست (Rest) چیه؟ ?

این پارامتر به ما کمک می‌کنه تابعی داشته باشیم که بی‌نهایت ورودی می‌گیره. بدون اینکه نیاز داشته باشیم تک تک ورودی‌ها رو تعریف کنیم.

ساختار پارامتر رست مقداری متفاوت با پارامترهای معمولی که توی توابع داشتیم هست. این پارامتر با گذاشتن سه‌نقطه ... قبل از اسم یک پارامتر ساخته میشه:

function add(...numbers) {

}

حالا تابع add می‌تونه بی‌نهایت ورودی داشته باشه، بدون اینکه مجبور بشیم برای هر تعداد ورودی تابع رو دستکاری کنیم ?

الان مقدار پارامتر numbers یک آرایه متشکل از همه ورودی‌هایی هست که به تابع پاس داده میشه. کد زیر رو اجرا کنین و کنسول مرورگر رو ببینین:

function add(...numbers) {
  console.log(numbers);
}

add(1, 3);
add(2, 5, 8);
add(3, 7, 11, 15);

همونطور که می‌بینیم استفاده کردن از تابعی که پارامتر رست داره هیچ تفاوتی با بقیه توابع نداره.

حالا می‌تونیم خیلی راحت تابع add رو بازنویسی کنیم. کافیه یک حلقه ساده روی numbers که یک آرایه هست بزنیم:

function add(...numbers) {
  let sum = 0;

  for (let i = 0; i < numbers.length; i++) {
    sum += numbers[i];
  }

  alert(sum);
}

add(1, 3);          // 4
add(2, 5, 8);       // 15
add(3, 7, 11, 15);  // 36



قوانین استفاده از پارامتر رست

هنگام تعریف کردن این پارامترها باید نکته‌های زیر رو در نظر داشته باشیم:

۱. بعد از پارامتر رست هیچ پارامتر دیگه‌ای نباید قرار بگیره:

const add = (...a, b) => {}

// Error: parameter after rest parameter

پس اگه تابعی داریم که شامل پارامترهای معمولی هم میشه، پارامتر رست رو باید آخرین پارامتر تعریف کنیم:

function welcome(msg, ...users) {
  // ...
}


۲. یک تابع فقط می‌تونه یک پارامتر رست داشته باشه:

const add = (...a, ...b) => {}

// Error: parameter after rest parameter



تفاوت پارامتر رست و آبجکت arguments

توی همه توابع معمولی (نه Arrow Function ها) یک متغیر وجود داره به اسم arguments که کاربرد اون مشابه پارامتر رست هست و تا قبل از معرفی این پارامتر، تنها راه داشتن توابعی با تعداد ورودی‌های دلخواه بود:

function add() {
  console.log(arguments);
}

add(1, 2, 3); // Arguments { 0: 1, 1: 2, 2: 3}

برخلاف پارامتر رست که یک آرایه واقعی به حساب میاد، نوع arguments یک آبجکت هست. اما به اون می‌گن آبجکت شبیه به آرایه. به این دلیل که ورودی‌های تابع توی این آبجکت، از طریق پراپرتی‌هایی قابل دسترسی هست که کلید اونها مثل آرایه‌ها با شماره‌های 0 و 1 و ... شروع میشه. همچنین شامل پراپرتی length هست که تعداد ورودی‌ها رو نشون میده.

با توجه به آرایه نبودن arguments، خیلی از متدهای پرکاربرد آرایه‌ها برای arguments قابل دسترس نیست و این موضوع مقداری کار رو دشوار می‌کنه. همچنین همونطور که گفتیم Arrow Function ها چنین متغیری توی خودشون ندارن:

const f = () => {
  console.log(arguments);
}

f(); // ReferenceError: arguments is not defined

با این توضیحات، پیشنهاد میشه که برای داشتن تعداد پارامترهای دلخواه از روش مدرن‌تر یعنی پارامتر رست استفاده بشه.



خب دوستان با پارامتر رست آشنا شدیم و دیدیم که چطوری با اون می‌تونیم علاوه‌بر اینکه حجم کدنویسی رو کمتر کنیم، کدهایی خواناتر و با قابلیت توسعهٔ بیشتری داشته باشیم.

روزتون خوش ?


Resources: developer.mozilla.org