Tạo máy tính (JS)

Sep 30 2020

Tôi có một dòng calc(2).add(3).add(5).res()và cần viết một giải pháp để tôi có 10kết quả. Tôi đã thử cái này

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())

nhưng trong trường hợp của tôi, tôi vượt qua 2trong new Calc(2), không phải trong calc(2). Làm thế nào tôi có thể thay đổi nó?

Sẽ thực sự biết ơn vì bất kỳ sự giúp đỡ nào!

Trả lời

1 VLAZ Sep 30 2020 at 19:26

Bạn có thể có một giải pháp thanh lịch tận dụng sức mạnh của việc đóng cửa:

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}
`)
}

Các calcchức năng có số lượng ban đầu được gọi xvà trả về một đối tượng với hai phương pháp:

  • res() chỉ trả lại số
  • add()sẽ nhận một tham số y, tính tổng với nó xvà gọi calclại với kết quả.

Vì vậy, giao diện của bạn hoàn toàn nhất quán: calc(10)sẽ giống như calc(3).add(7)hoặc calc(8).add(2)hoặc calc(2).add(3).add(5). Bạn có thể xâu chuỗi các addcuộc gọi bao nhiêu tùy thích và nó sẽ luôn giống nhau. Cuộc gọi res()sẽ kết thúc chuỗi và chỉ cung cấp cho bạn số calchiện đang giữ - cho dù bạn đã thực hiện calc(10).res()hay chưa calc(2).add(3).add(5).res().

Mã có thể được rút ngắn rất nhiều bằng cách sử dụng các hàm mũi tên:

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}
`)
}

Các thao tác khác cũng có thể dễ dàng được thêm vào bằng cách sử dụng cùng một mẫu:

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}
`)
}

Lưu ý rằng vì mỗi thao tác được thực thi ngay lập tức, vì vậy ưu tiên duy nhất mà bạn hiện có là thứ đến trước.

3 alotropico Sep 30 2020 at 18:46

Nếu tôi hiểu đúng, đây sẽ là một cách để làm điều đó:

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())

DerekWang Sep 30 2020 at 18:49

Bạn có thể định nghĩa calcnhư một hàm trả về đối tượng Calc.

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())