Вы, наверное, уже знаете, что JavaScript — невероятно гибкий язык. Я хотел бы поделиться одним из моих любимых примеров того, что это действительно позволяет вам делать.

Начнем с создания функции add, которая принимает два аргумента, a и b, и возвращает сумму:

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

Довольно прямо вперед; однако что, если вы захотите добавить второе число позже? Скажем, вы хотели бы сделать следующее:

var addFour = add(4);
...
addFour(2) // returns 6

На самом деле это можно сделать с помощью метода под названием каррирование, которое оказалось одним из краеугольных камней функционального программирования. Не пугайтесь, это проще, чем вы думаете:

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

По сути, он возвращает новую функцию, на которую будет ссылаться addFour в приведенном выше примере. Я сделаю это кристально ясным:

var addFour = add(4); // returns a function
addFour = (b) => 4 + b; // reference to function

Круто, да?

Однако не было бы удобнее иметь возможность делать это бесконечно?

Невозможно, верно? Нет, не в JS. Оказывается, мы можем изменить значение самой функции, чтобы вернуть примитивное значение, которое является нашей суммой. В сочетании с возможностью возвращать функции мы можем легко написать что-то вроде этого:

const add = (sum) => {
  const fn = (b) => add(sum + b);
  
  fn.valueOf = () => sum;
  
  return fn;
}

Теперь мы можем вызвать функцию следующим образом:

add(2)(3)(4)(2) // returns 11
add(1)(2) // returns 3
add(3)(1)(4) + 3 // returns 11

Надеюсь, вам понравилось чтение! :)