Buat kalkulator (JS)

Sep 30 2020

Saya memiliki garis calc(2).add(3).add(5).res()dan perlu menulis solusi sehingga saya mendapatkan 10hasilnya. Saya mencoba ini

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

tapi dalam kasus saya saya lulus 2di new Calc(2), tidak calc(2). Bagaimana saya bisa mengubahnya?

Akan sangat berterima kasih atas bantuan apa pun!

Jawaban

1 VLAZ Sep 30 2020 at 19:26

Anda dapat memiliki solusi elegan yang memanfaatkan kekuatan closure:

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

The calcFungsi mengambil jumlah awal yang disebut xdan mengembalikan sebuah objek dengan dua metode:

  • res() hanya mengembalikan nomornya
  • add()akan mengambil parameter y, menjumlahkannya dengan xdan memanggil calclagi dengan hasilnya.

Jadi, antarmuka Anda sepenuhnya konsisten: calc(10)akan sama dengan calc(3).add(7)atau calc(8).add(2)atau calc(2).add(3).add(5). Anda dapat menyambung addpanggilan sebanyak yang Anda inginkan dan itu akan selalu sama. Menelepon res()akan mengakhiri rantai dan hanya memberi Anda nomor yang calcsaat ini memegang - apakah Anda sudah selesai calc(10).res()atau calc(2).add(3).add(5).res().

Kode dapat banyak dipersingkat menggunakan fungsi panah:

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

Operasi lain juga dapat dengan mudah ditambahkan menggunakan pola yang sama:

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

Perhatikan bahwa karena setiap operasi dijalankan segera, jadi satu-satunya prioritas yang Anda miliki saat ini adalah apa yang didahulukan.

3 alotropico Sep 30 2020 at 18:46

Jika saya mengerti dengan benar, ini akan menjadi cara untuk melakukannya:

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

Anda dapat mendefinisikan calcsebagai fungsi yang mengembalikan objek 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())