How to pass a method defined on a prototype to Array.map as a callback

I have an array

var arr = [' A ', ' b ', 'c']; 

and I want to trim spaces from each element from the array.

This can be done using Array.map as

 arr.map(function(el) { return el.trim(); }); 

I am interested in passing the trim / toLowerCase directly to map as a callback function, for example arr.map (Math.max.apply.bind (Math.max, null)); to get the maximum element from each subarray or arr.map (Number); to display each element in Number.

I tried

 arr.map(String.prototype.trim.apply); 

but he throws a mistake

Uncaught TypeError: Function.prototype.apply was called on undefined, which is undefined, not a function

I expect that for each element of the array String.prototype.trim.apply should be called with the context set to the element from the array (passed to apply );

I also tried different combinations of apply , call and bind without success.

  • Why can't I use the prototype link when using map
  • The function can be passed as a map parameter
+6
source share
2 answers
 arr.map(String.prototype.trim.call.bind(String.prototype.trim)); 

call uses this internally, which should point to the trim function to work correctly in this case. Just passing String.prototype.trim.call left the call unconnected with any method, as a result of which this value will point to window .

It works, but when used it is used instead of calling, it throws an error, arr.map (String.prototype.trim.apply.bind (String.prototype.trim));

The problem is that map will pass 2 arguments, an element and an index. Therefore, it calls a call of something like 'String.prototype.trim.apply('test', 0) , which fails because the second argument must be an array.

one more thing ['A', 'B', 'C']. Map (String.prototype.trim.call.bind (String.prototype.toLowerCase)) ;, in this I used trim.call and passed toLowerCase as the context, then why do we need to trim here, why the trim is not called

When using call.bind path that you chose to access the call function becomes irrelevant. The function to be called is called.

If you want to compose functions, you will need a different approach:

 var call = Function.prototype.call, trim = call.bind(String.prototype.trim), toLowerCase = call.bind(String.prototype.toLowerCase), trimAndLowerCase = pipelineFrom(trim, toLowerCase); [' TeST '].map(trimAndLowerCase); function pipelineFrom(fn1, fn2) { return function (val) { return fn2(fn1(val)); }; } 

However, at this point you will be better off:

 arr.map(function (val) { return val.trim().toLowerCase(); }); 
+5
source

This works, of course, it is long, but:

 var t = String.prototype.trim.call.bind(String.prototype.trim); arr.map(t); 

Because it is longwinded there are blog posts and modules dedicated to the messy things you are trying to do here.

I asked about it here ...

+2
source

All Articles