Reputation: 490283
I have an array of strings. I want to trim each string in the array.
I thought using [].map()
with ''.trim()
would work...
[' a', ' b ', 'c'].map(String.prototype.trim);
...but my console said...
TypeError: String.prototype.trim called on null or undefined
I can't see any null
or undefined
values in my array.
String.prototype.trim()
and Array.prototype.map()
are defined in Chrome 17, which I'm using to test.
Why doesn't this work? I get the feeling I have overlooked something obvious.
I realise I could loop or drop a function in there. That's not the point of this question, however.
Upvotes: 25
Views: 7239
Reputation: 1
That's because trim
is not being called with the proper this
context. Remember that this
is dynamically bound in JS. You will have to create a wrapper to pass to trim
to properly bind this
:
[' a', ' b ', 'c'].map(function (str) {
return str.trim();
});
Upvotes: 25
Reputation: 600
With ES6 syntax it can be as easy as this:
[' hello ', ' world'].map(str => str.trim());
Upvotes: 3
Reputation: 76218
What @Slace says is the right explanation. @ThomasEding's answer also works but has one terrible inefficieny that it may create functions within a loop, which is not a good thing to do.
Another way of doing would be (reference here):
[' a', ' b ', 'c'].map(Function.prototype.call, String.prototype.trim);
// gives ["a", "b", "c"]
Standard browser disclaimer: This will work wherever Function.prototype.call
and String.prototype.trim
will work and for older browsers, you can easily substitute trim
with a polyfill like this:
if(!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g,'');
};
}
Update: Interstingly, while this works fastest in Chrome, @ThomasEding's method runs slightly faster in IE10 and FF20 - http://jsperf.com/native-trim-vs-regex-trim-vs-mixed
Upvotes: 35
Reputation: 25097
trim
is on the String
prototype, meaning that it expects the this
context to be that of a string where as the map
method on Array
provides the current array item as the first argument and the this
context being the global object.
Upvotes: 20