1

How come

var a = "foo /    bar/  baz  ".split('/');

a.map( function (e) { return String.prototype.trim.call(e) } )

works, while this doesn't...

a.map( String.prototype.trim );
Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
  • may be this helps.. http://stackoverflow.com/questions/21186398/cant-use-string-prototype-trim-method-as-a-callback-for-array-map-filter – Sudhir Bastakoti Jan 05 '15 at 09:42
  • 1
    The answers are useful, but to keep yourself sane, you could also just do `a.map(function(e) { return e.trim(); })`. –  Jan 05 '15 at 10:44
  • possible duplicate of [JS Array.prototype.filter on prototype method](http://stackoverflow.com/questions/25214922/js-array-prototype-filter-on-prototype-method) –  Jan 05 '15 at 11:57
  • As pointed out in the question suggested as duplicate, one elegant solution is `a.map(Function.call, "".trim)`. –  Jan 05 '15 at 11:58
  • 1
    Or, you could simply do `split(/\s*\/\s*/)` and save yourself the mapping/trimming trouble. –  Jan 05 '15 at 12:07

3 Answers3

1

Try this:

a.map(Function.prototype.call.bind(String.prototype.trim ))

The reason why this works and just mapping String.prototype.trim doesn't work is because, as others have pointed out, the this will be undefined when the function tries to trim the array element. What this solution does is, it creates a new function, which takes as it's this value as the function String.prototype.trim. Since the new function is a modified version of Function.prototype.call, as map calls this function passing it the array element, what essentially gets executed is: Function.prototype.call.call(String.prototype.trim, element). This runs the function String.prototype.trim on the element passed in and you get the trimmed result. This also would work:

 a.map(Function.call, "".trim)

by taking advantage of the fact that the second argument to map accepts the thisArg. For a little bit of syntactic sugar, you can make a function that looks like this:

Array.prototype.mapUsingThis = function(fn) { return this.map(Function.call, fn); };

Then, you could just invoke

a.mapUsingThis("".trim)

like that.

Hrishi
  • 7,110
  • 5
  • 27
  • 26
0

String.prototype.trim is a non params function, it will be called by string itself, but map function need a func arg accept a str as params

笑笑十年
  • 101
  • 5
0

'this' refers to the string param in the first case whereas in the second case, 'this' becomes undefined as String.prototype.trim is not bound to any object.