Your operation
argument is just a String, not a real operator. This is why it doesn't works as you'd like. So, you have some alternatives.
Using Eval
You could use the eval
function to dinamically run a String as a piece of code, this way:
function calculate(x, y, operation) {
return eval(x + operation + y)
}
While it seems so consise and clear, keep in mind that it's commonly a bad practice, for security, manutenibility and performance reasons (more about it here).
Using Conditionals
Sometimes the simplest idea is the best option: just use some conditionals.
function calculate(x, y, operation) {
if (operation === '+') return x + y
else if (operation === '-') return x - y
else if (operation === '*') return x * y
else if (operation === '/') return x / y
else if (operation === '%') return x % y
else if (operation === '**') return x ** y
else return NaN
}
It may seems a little repetitive, but keep in mind that you don't have a lot of arithmetic operations to handle. In fact, all the binary arithmetic operators are handled above.
An alternative syntax wold be a switch case
statement, but it's just a more verbose conditional structure, the ideia remains the same.
Using an Object with Functions
Another approach, strongly inspired by Nina Scholz' answer, is mapping String representations of operators with they equivalent function, with the help of an Object:
function calculate(x, y, operation) {
var operators = {
'+': function (a, b) { return a + b },
'-': function (a, b) { return a - b },
'*': function (a, b) { return a * b },
'/': function (a, b) { return a / b },
'%': function (a, b) { return a % b },
'**': function (a, b) { return a ** b }
}
return operation in operators ? operators[operation](x, y) : NaN
}
If on an ES2015+ environment (see the compatibility), arrow functions can make it very elegant:
function calculate(x, y, operation) {
const operators = {
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
'/': (a, b) => a / b,
'%': (a, b) => a % b,
'**': (a, b) => a ** b
}
return operation in operators ? operators[operation](x, y) : NaN
}
While I personally still believe that the simple conditional statements are enough for this case, this Object approach is very interesting to show a little about the JavaScript's flexibility.