console.log(Function.prototype.apply.call(Math.floor, undefined, [1.75]));
is giving one but
console.log(Function.prototype.apply(Math.floor, undefined, [1.75]));
returning undefined what is happening here?
I tryed googling but didn't get any good answers.
CodePudding user response:
Function.prototype.apply
is just the implementation of the apply
method that all functions inherit. Calling it will returned undefined
because there is no actual function to modify. Instead, it should be used like: Math.floor.apply(undefined, [1.75])
.
Function.prototype.apply.call
on the other hand is just a way to use the apply
method without having to worry about it being overriden for the specific function.
CodePudding user response:
Let's do the second one (the not-working one) first.
Normally, .apply()
is used as
someFunction.apply(thisValue, argsArray)
That has an effect like if thisValue
were some random object and you had
thisValue.someFunction = someFunction;
thisValue.someFunction(... argsArray)
The function is called with the value of this
being whatever the first argument is, and the list of arguments being the contents of the array. Inside the .apply()
function itself, the this
value is a reference to the function to be called.
Thus, in
Function.prototype.apply(Math.floor, undefined, [1.75])
we have the .apply()
function being called such that its own this
value is Function.prototype
, which is a function that always returns undefined
. Thus, that function is called with Math.floor
(a function) as the value of this
, and no arguments, because the third argument is ignored. The Function.prototype
function returns undefined
because that's what it always does.
OK, so now for the first example:
Function.prototype.apply.call(Math.floor, undefined, [1.75])
Here we have code involving both .apply()
and .call()
. What will be called in sequence are:
Function.prototype.call
Function.prototype.apply
Math.floor
The .call()
function is the start of the chain. It's called, and internally its this
value will be the .apply()
function. So what that means is that we want to call apply
with the list of arguments (and a this
value) taken from the arguments to .call()
. In this case, that means .apply()
will be called so that its internal this
value will be Math.floor
, which makes sense because that means the real function we ultimately want to invoke is Math.floor()
. Then, the argument list to .call()
passes undefined
as the first argument to .apply()
, meaning that the value of this
when Math.floor()
is called will be undefined
. Finally the third argument to .call()
is the array with 1.75 in it, which means that Math.floor()
will be invoked with one argument, that being 1.75, and it dutifully returns 1.