创建计算器 (JS)

Create calculator (JS)

我有一行 calc(2).add(3).add(5).res() 并且需要编写一个解决方案以便我得到 10 作为结果。 我试过这个

class Calc{
    constructor(num){
        this.num = num
    }

    add(a){
        this.num += a;
        return this;
    }

    res() {
        return this.num;
    }
}
let calc = new Calc(2)
console.log(calc.add(3).add(5).res())

但在我的例子中,我在 new Calc(2) 中传递了 2,而不是在 calc(2) 中。我该如何更改它?

非常感谢您的帮助!

如果我没理解错的话,应该是这样的:

class Calc{
    constructor(num){
        this.num = num
    }

    add(a){
        this.num += a;
        return this;
    }

    res() {
        return this.num;
    }
}
let calc = function(num){ return new Calc(num) }
console.log(calc(2).add(3).add(5).res())

您可以将 calc 定义为 returns 计算对象的函数。

class Calc{
    constructor(num){
        this.num = num
    }

    add(a){
        this.num += a;
        return this;
    }

    res() {
        return this.num;
    }
}

const calc = (input) => new Calc(input);
console.log(calc(2).add(3).add(5).res())

您可以拥有一个利用闭包功能的优雅解决方案:

function calc(x) {
  return {
    res: function() {
      return x;
    },
    add: function(y) {
      return calc(x + y)
    }
  }
}

test(
  10,
  calc(10).res()
);
test(
  10,
  calc(3).add(7).res()
);
test(
  10,
  calc(8).add(2).res()
);
test(
  10,
  calc(2).add(3).add(5).res()
);


function test(expected, actual) {
  console.log(
`result is: ${actual}
correct: ${actual === expected}
`)
}

calc 函数采用名为 x 的初始数字和 returns 具有两种方法的对象:

  • res()只是returns这个数字
  • add() 将采用参数 y,将其与 x 相加,然后用结果再次调用 calc

因此您的界面是完全一致的:calc(10) 将与 calc(3).add(7)calc(8).add(2)calc(2).add(3).add(5) 相同。您可以根据需要尽可能多地链接 add 调用,并且它始终是相同的。调用 res() 将结束链并只给你 calc 当前持有的数字 - 无论你已经完成 calc(10).res()calc(2).add(3).add(5).res().

使用箭头函数可以大大缩短代码:

const calc = x => ({
  res: () => x,
  add: y => calc(x + y)
});

test(
  10,
  calc(10).res()
);
test(
  10,
  calc(3).add(7).res()
);
test(
  10,
  calc(8).add(2).res()
);
test(
  10,
  calc(2).add(3).add(5).res()
);


function test(expected, actual) {
  console.log(
`result is: ${actual}
correct: ${actual === expected}
`)
}

也可以使用相同的模式轻松添加其他操作:

const calc = x => ({
  res: () => x,
  add: y => calc(x + y),
  sub: y => calc(x - y),
  mul: y => calc(x * y),
  div: y => calc(x / y)
});

test(
  2,
  calc(5).add(5).mul(2).sub(4).div(8).res()
  // (((5 + 5) * 2) - 4) / 8 = 
  // ((10 * 2) - 4) / 8 = 
  // (20 - 4) / 8 = 
  // 16 / 8 = 2
);


function test(expected, actual) {
  console.log(
`result is: ${actual}
correct: ${actual === expected}
`)
}

请注意,由于每个操作都是立即执行的,因此您目前拥有的唯一优先权是先到先得。