var array1 = [1, 4, 9, 16];
map1=array1.map(Function.call,Number);
Why the output of map1 is [0,1,2,3], what this map function is doing?
Array.prototype.map calls the function provided for each member of the array, and returns a new array of their return values.
In this case, the provided function is Function.call.
The second argument to Array.prototype.map
specifies the context in which the provided function should run.
In this case, the context is Number.
A naive implementation of Array.prototype.map
could look something along the lines of:
function map(callback, thisArg) {
const ret = []
for (let index = 0; index < this.length; index++) {
const value = this[index]
ret.push(callback.call(thisArg, value, index, this))
}
return ret
}
Now, this particular case uses a lot of indirection so it's not easy to see why passing Function.call
and Number
should return [0, 1, 2, 3]
, so lets walk through that part.
When the callback
(Function.call
) is called in the context of the thisArg
(Number
) the code will execute something along the lines of:
(Function.call).call((Number), (1), (0), ([1, 4, 9, 16]))
// ^-- callback ^-- value ^-- array
// ^-- thisArg ^-- index
Evaluating Function.call.call(...)
is a bit of a mind-bender, but it amounts to calling the call
function in the context of the first parameter, which should be a function. In our case, it is. It's the Number
function.
We can then simplify this statement to look like:
Number.call(1, 0, [1, 4, 9, 16])
The Number
function converts the first parameter to a number. Other parameters are ignored, along with the functions context. This means the entire expression can be simplified to:
Number(0)
where 0
was the index
.
This is why the return value is [0, 1, 2, 3]
, as these are the indices from the original array.
It should go without saying that the original code sample is not something that should ever be used in day-to-day programming. The entire system would have been simpler to use:
[1, 4, 9, 16].map((value, index) => index)
and even then it should be noted that the original values are being thrown out uselessly. Such code samples are useful only in the academic sense of exploring behaviors of a particular language, or when you want to intentionally confuse your friends as part of a coding challenge.