написать функции plus(number) и minus(number) так, чтобы можно было посчитать результат цепочкой вызовов

Тест кейсы вот такие

    plus(1).plus(2).value() ;  // 3
    plus(1).plus(10).minus(3).plus(8).value() // 16 

Я смог сделать только так:

            let result = {
            sum: 0,
            plus(num) {
                this.sum += num;
                return this;
            },
            minus(num) {
                this.sum -= num;
                return this;
            },
            value: function() {
                console.log(this.sum);
                this.sum = 0
                
            },
        };

        result.plus(1).plus(2).value() ;  // 3
        result.plus(1).plus(10).minus(3).plus(8).value() // 16

Но надо, чтобы в тест кейсах не было result, а было четко как в задании


Ответы (2 шт):

Автор решения: OPTIMUS PRIME

Нужны две дополнительные одноименные функции, которые будут запускать счет.

const MATH = {
  sum: 0,

  plus(num) {
    this.sum += num;
    return this;
  },
  minus(num) {
    this.sum -= num;
    return this;
  },
  value: function() {
    console.log(this.sum);
  },
};

// Отдельные функции, начнающие цепочку. "Обнуляют" сумму, выставив ей значение `n`
function plus(n) {
  MATH.sum = n;
  return MATH;
};
function minus(n) {
  MATH.sum = -n;
  return MATH;
};

/***/
plus(1).plus(2).value(); // 3
plus(1).plus(10).minus(3).plus(8).value(); // 16
minus(15).value(); // -15

Можно еще воспользоваться тем, что функции - тоже объекты, с ними можно обращаться как с обычными объектами. Например, каждой функии выдать свойства plus, minus, которые будут ссылаться на соответствующие функции:

let sum = 0;

function plus(n) {
  sum += n;
  return plus;
}

function minus(n) {
  sum -= n;
  return minus;
}

function value() {
  console.log(sum);
  sum = 0;
}

plus.minus = minus.minus = minus;
minus.plus = plus.plus = plus;
plus.value = minus.value = value;

/***/
plus(1).plus(2).value(); // 3
plus(1).plus(10).minus(3).plus(8).value(); // 16
minus(15).value(); // -15

→ Ссылка
Автор решения: Grundy

Чтобы работала цепочка вызовов, нужно чтобы каждая функция возвращала объект, с необходимыми полями. В данном случае в объекте должно быть три метода:

  1. plus
  2. minus
  3. value

Так же в возвращаемом объекте можно хранить и текущее значение

В итоге код может выглядеть так:

function plus(num) {
  return {
    sum: this === globalThis ? num : (this.sum + num),
    plus,
    minus,
    value() {
      return this.sum;
    }
  }
}

function minus(num) {
  return {
    sum: this === globalThis ? -num : (this.sum - num),
    plus,
    minus,
    value() {
      return this.sum;
    }
  }
}

console.log(plus(1).plus(2).value()); // 3
console.log(plus(1).plus(10).minus(3).plus(8).value()); // 16

console.log(minus(1).plus(2).value()); // 3

Также можно обойтись и без свойства sum

function calc(sum) {
  return {
    plus: num => calc(num + sum),
    minus: num => calc(sum - num),
    value() {
      return sum;
    }
  }
}

let plus = calc;
let minus = num => calc(-num);

console.log(plus(1).plus(2).value()); // 3
console.log(plus(1).plus(10).minus(3).plus(8).value()); // 16

console.log(minus(1).plus(2).value()); // 3

→ Ссылка