I have a line calc(2).add(3).add(5).res()
and need to write a solution so that I have 10
as a result. I tried this
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())
but in my case I pass 2
in new Calc(2)
, not in calc(2)
. How can I change it?
Will be really grateful for any help!
If I understood correctly, this would be a way to do it:
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())
You can have an elegant solution leveraging the power of closures:
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 calc
function takes the initial number called x
and returns an object with two methods:
res()
just returns the number add()
will take a parameter y
, sums it with x
and calls calc
again with the result. So your interface is entirely consistent: calc(10)
is going to be the same as calc(3).add(7)
or calc(8).add(2)
or calc(2).add(3).add(5)
. You can chain the add
calls as much as you want and it's always going to be the same. Calling res()
will end the chain and just give you the number that calc
currently holds - whether you've done calc(10).res()
or calc(2).add(3).add(5).res()
.
The code can be shortened a lot using arrow functions:
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} `) }
Other operations can also easily be added using the same pattern:
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} `) }
Note that since each operation is executed immediately, so the only precedence you currently have is what comes first.
You can define calc
as function that returns Calc object.
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())
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.