zpět k lekci

Sčítání s libovolným počtem závorek

důležitost: 2

Napište funkci sečti, která bude fungovat takto:

sečti(1)(2) == 3; // 1 + 2
sečti(1)(2)(3) == 6; // 1 + 2 + 3
sečti(5)(-1)(2) == 6
sečti(6)(-1)(-2)(-3) == 0
sečti(0)(1)(2)(3)(4)(5) == 15

P.S. Rada: možná budete pro svou funkci potřebovat nastavit vlastní konverzi objektu na primitiv.

Otevřít pískoviště s testy.

  1. Aby to celé jakkoli fungovalo, výsledek funkce sečti musí být funkce.
  2. Tato funkce si musí udržovat v paměti aktuální hodnotu mezi voláními.
  3. Podle zadání se funkce musí stát číslem, když je použita v ==. Funkce jsou objekty, takže konverze se odehrává tak, jak je popsáno v kapitole Konverze objektů na primitivní typy, a my můžeme poskytnout svou vlastní metodu, která toto číslo vrátí.

Nyní kód:

function sečti(a) {

  let aktuálníSoučet = a;

  function f(b) {
    aktuálníSoučet += b;
    return f;
  }

  f.toString = function() {
    return aktuálníSoučet;
  };

  return f;
}

alert( sečti(1)(2) ); // 3
alert( sečti(5)(-1)(2) ); // 6
alert( sečti(6)(-1)(-2)(-3) ); // 0
alert( sečti(0)(1)(2)(3)(4)(5) ); // 15

Prosíme všimněte si, že funkce sečti se ve skutečnosti spustí jenom jednou. Vrátí funkci f.

Pak funkce f při každém následném volání přičte svůj parametr k součtu aktuálníSoučet a vrátí sebe sama.

Na posledním řádku funkce f není rekurze.

Rekurze by vypadala takto:

function f(b) {
  aktuálníSoučet += b;
  return f(); // <-- rekurzívní volání
}

V našem případě vracíme jen funkci, aniž bychom ji volali:

function f(b) {
  aktuálníSoučet += b;
  return f; // <-- nevolá sama sebe, vrací sama sebe
}

Tato funkce f bude použita při dalším volání a opět vrátí sebe sama, tolikrát, kolikrát je zapotřebí. Když ji pak použijeme jako číslo nebo řetězec, toString vrátí aktuálníSoučet. Zde bychom pro konverzi mohli také použít Symbol.toPrimitive nebo valueOf.

Otevřít řešení s testy na pískovišti.