You can do it that way, but you have to use .call (or .apply) so you set this correctly within the call to toUpperCase/toLowerCase, since they expect to see the string to use as this, not as a passed parameter:
let func = flag ? String.prototype.toUpperCase : String.prototype.toLowerCase;
arr = arr.map(x=>func.call(x));
//-------------------^^^^^
(I also dropped the let from in front of arr on the second line, as otherwise arr on the right-hand side of the = would be undefined. [Or, depending on where/how arr was previously declared, it would be an error.])
Example:
let arr = ["one", "TWO", "three", "FOUR"];
const flag = Math.random() < 0.5;
console.log("Flag is: " + flag);
let func = flag ? String.prototype.toUpperCase : String.prototype.toLowerCase;
arr = arr.map(x=>func.call(x));
console.log(arr);
Another option is to give yourself a wrapper function, which you can then call the way you wanted to call it:
let func = flag ? s => s.toUpperCase() : s => s.toLowerCase();
arr = arr.map(x=>func(x));
Example:
let arr = ["one", "TWO", "three", "FOUR"];
const flag = Math.random() < 0.5;
console.log("Flag is: " + flag);
let func = flag ? s => s.toUpperCase() : s => s.toLowerCase();
arr = arr.map(x=>func(x));
console.log(arr);
But the easier thing in this specific case is to just use brackets notation and a string function name:
let funcName = flag ? "toUpperCase" : "toLowerCase";
arr = arr.map(x=>x[funcName]());
Example:
let arr = ["one", "TWO", "three", "FOUR"];
const flag = Math.random() < 0.5;
console.log("Flag is: " + flag);
let funcName = flag ? "toUpperCase" : "toLowerCase";
arr = arr.map(x=>x[funcName]());
console.log(arr);
x, not pass it as an argument..callfor such things (or .apply, whatever).