بازگشت به درس

جمع زدن با تعداد دلخواهی از پرانتز

اهمیت: 2

تابع sum را بنویسید که اینگونه کار کند:

sum(1)(2) == 3; // 1 + 2
sum(1)(2)(3) == 6; // 1 + 2 + 3
sum(5)(-1)(2) == 6
sum(6)(-1)(-2)(-3) == 0
sum(0)(1)(2)(3)(4)(5) == 15

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

باز کردن یک sandbox همراه با تست‌ها.

  1. برای اینکه همه چیز به هر نحوی کار کند، نتیجه sum باید تابع باشد.
  2. آن تابع باید بین فراخوانی‌ها مقدار کنونی را در حافظه ذخیره کند.
  3. با توجه به تمرین، تابع باید زمانی که با == استفاده می‌شود، تبدیل به عدد شود. تابع‌ها شیء هستند پس تبدیل شدن همانطور که در فصل تبدیل شیء به مقدار اصلی گفته شد اتفاق می‌افتد و ما می‌توانیم متد خودمان را برای برگرداندن عدد بسازیم.

حالا می‌رسیم به کد:

function sum(a) {

  let currentSum = a;

  function f(b) {
    currentSum += b;
    return f;
  }

  f.toString = function() {
    return currentSum;
  };

  return f;
}

alert( sum(1)(2) ); // 3
alert( sum(5)(-1)(2) ); // 6
alert( sum(6)(-1)(-2)(-3) ); // 0
alert( sum(0)(1)(2)(3)(4)(5) ); // 15

لطفا در نظر داشته باشید که تابع sum فقط یکبار کار می‌کند. تابع f را برمی‌گرداند.

سپس در هر فراخوانی زیر مجموعه آن، تابع f پارامتر خودش را به جمع currentSum اضافه می‌کند و خودش را برمی‌گرداند.

هیچ بازگشتی در آخرین خط f وجود ندارد.

بازگشتی اینگونه بنظر می‌رسد:

function f(b) {
  currentSum += b;
  return f(); // <-- فراخوانی بازگشتی
}

و در این مورد ما، بدون صدا زدن تابع، ما فقط آن را برمی‌گردانیم:

function f(b) {
  currentSum += b;
  return f; // <-- خودش را صدا نمی‌زد، خودش را برمی‌گرداند
}

این f در فراخوانی بعدی استفاده می‌شود و دوباره خودش را برمی‌گرداند، هر چند باری که نیاز باشد. سپس زمانی که به عنوان یک عدد یا رشته استفاده می‌شود – toString مقدار currentSum را برمی‌گرداند. ما می‌توانستیم برای تبدیل از Symbol.toPrimitive یا valueOf اینجا استفاده کنیم.

باز کردن راه‌حل همراه با تست‌ها درون یک sandbox.