What MDN is doing:
slice
is a method of Array objects, but can be applied to array like objects, such as arguments
which have a length and numeric string property names, to convert the object into an actual Array object instance:
Array.prototype.slice.apply( arguments)
Note this code does NOT call slice
with any parameter values. If any were required, they could be added as an array of values to the actual argument list of apply
. It works because slice
uses its this
value (set to arguments
) as the array like object, and will operate without any additional parameters.
apply
is a method of function objects, and in the code above, is inherited from Function.prototypeby the
slice` function.
Now break down the code in (1) above into two pieces:
const slice = Array.prototype.slice // a)
slice.apply( arguments) // b) and c)
a) creates a reference to the slice
function stored in Array.prototype
.
b) calls slice
's apply
method, inherited from Function.prototype
, with a this
value of slice
for simple reason that apply
is being called as a method of slice
.
c) apply
calls its this
value (slice
) with slice
's this
value set to the first argument supplied to apply
.
But notice in the broken down code the apply
function is called with a constant this
value - namely the slice
function. If we bind apply
to slice
we can compress all the steps into a single function call:
const slice = Array.prototype.slice;
const boundApply = slice.apply.bind(slice);
making boundApply( arguments)
equivalent to
Function.prototype.apply.bind(Array.prototype.slice)(arguments)
While the MDN example puts this bound version of apply
in a variable called slice
, the resultant function's argument syntax is that of Function.prototype.apply
. Because of this start
and end
parameters for slice
can be added as the second and third arguments of the bound function.
Hence your example needs to supply an argument list suitable for apply
, not add
function add(num1, num2){
return num1 + num2;
}
var test = Function.prototype.apply.bind(add);
var result = test(null, [1,2])
The reply from @Ryan shows how to wrap this into a single function that does not require null
.
Summary
Function.prototype.bind
is used to create an exotic function with a specific this
value. Even if you save the the bound function as an object property and call it as a method of the object, the this
value it sees is the one that was supplied to bind
. This can be useful for, say, event handlers that use a this
value other than null
, window
or the element on which the event was fired.
Function.prototype.apply
allows you to dynamically supply the this
value of a called function. It may be more efficient than using bind
for a single call to an existing or anonymous function (because it does not require creating a bound function object) or may suit an application that wants to call the same function on multiple objects to be used as the function's this value.
Note that bind
and apply
only affect the this
value of functions declared using the function
keyword. You can not bind the this
value of arrow functions in JavaScript.