Chaining Function.apply.bind() in Return Largest Number in Arrays

Specifically looking at the advanced solution (I’ve solved it the other ways by myself):

function largestOfFour ( arr ) {
return arr.map ( Function.apply.bind ( Math.max, null ));
}

I get what its doing effectively in terms of creating a Math.max() function that takes an array argument but not how its doing it.

The major issue I am having trouble grasping is the behaviour of how Function.apply() or Function.bind() works versus an explicitly defined function such as in these 2 examples which I understand:

Going back to the solution, my best shot at reasoning what happens after map calls the chained function is:

1. Function.apply.bind ( Math.max, null, subArrayN );
2. Which breaks down to: Function.prototype.Math.max.apply ( null, subArrayN );
3. Which then breaks down to: Function.prototype.Math.max ( subArrayN );

Where Math.max is the this argument for bind, null is the this argument for apply, and subArray is the array argument that will be used when Function is called. However I can’t make complete sense of this logic and feel like I’m way out to lunch.

This is because in my current logic Math.max would be added as a property of the function prototype and not as the context in which Function.prototype is being called. Or is it that Math.max is passed directly as the context object on which apply is called; and Function is a way of making Math.max.apply globally available as a new property of the Function object prototype?

I’d love for someone to articulate where I’m going wrong, this has been a really big monkey on my back. The Function part is what I really have no clue about, the rest I’m merely just confused about :joy:. Thanks in advance, sorry for being so long winded folks.

Function is a global object. I’m not sure how it exactly works, but I’m sure that it’s just another function like Math.max or console.log (you can confirm by running typeof Function). Since it’s also a function, it also has access to the apply and bind functions.

I think Function here works just so you can access the apply function (which all functions have access to). You can replace Function with any other function and it will work just fine (like console.log.apply.bind(Math.max, null)).

I had no idea it works before looking at this but I thought I’d take a shot at this, too, as a learning exercise!

After much reading, I believe all the answers can actually be found in the MDN documentation. Have a look here and pay attention to the definition and the examples partially applied functions and creating shortcuts for bind(). Also have a look here regarding the Function constructor.

Going back to the code from the advanced solution:

function largestOfFour ( arr ) {
return arr.map ( Function.apply.bind ( Math.max, null ));
}

I believe the idea is to create a partially applied function so that it can be used with the map() method. With reference to the creating shortcuts section of the MDN documentation for bind(), Function.apply.bind(Math.max, null)) effectively creates a shortcut to Math.max.apply(null, ...), where ... are arguments waiting to be supplied, which will be an array because of map() (hence a partial function).

I think the advanced solution is functionally the same as the following code (tested on CodePen), which is probably easier to understand (at least for me it is):

var shortcut = function(subArray) {
    return Math.max.apply(null, subArray);
}

function largestOfFour(arr) {
    return arr.map(shortcut);
}

I hope that helps!

EDIT Typo!

2 Likes

I had the same problem. You saved my day. Thanks so much!
http://jsonformatter-online.com

It definitely does, thanks!