First, do it simply :
x.map(function(s) { return s.trim() });
Then, the reason why the first one doesn't work is that the string is passed as argument to the callback, not as context. As you pass no argument to apply, you get the same message you would have got with
var f = String.prototype.trim.apply; f.call();
Now, mostly for fun, let's suppose you're not happy with the fact that map use the callback this way and you'd want to be able to pass a function using the context, not the argument.
Then you could do this :
Object.defineProperty(Array.prototype, "maprec", {
value: function(cb){
return this.map(function(v){ return cb.call(v) })
}
});
console.log([' aa ', ' bb '].maprec(String.prototype.trim)); // logs ["aa", "bb"]
I said "mostly for fun" because modifying objects you don't own (Array's prototype here) is widely seen as a bad practice. But you could also make a utilitarian function taking both the array and the callback as arguments.