Alright, let's tackle this problem via substitution. We start with:
Function.prototype.call.apply(Array.prototype.slice, arguments);
What we know:
Function.prototype.call
is a function.
- The
this
pointer of call
points to Function.prototype
.
- We use
apply
to change the this
pointer of call
to Array.prototype.slice
.
arguments
is applied (not passed as a parameter) to call
.
Thus the above statement is equivalent to:
Array.prototype.slice.call(arguments[0], arguments[1], ...);
From this we see:
Array.prototype.slice
is a function.
- The
this
pointer of slice
points to Array.prototype
.
- We use
call
to change the this
pointer of slice
to arguments[0]
.
arguments[1], ...
are passed as parameters to slice
.
This is the same as:
arguments[0].slice(arguments[1], ...);
The advantage of this is that we're creating a fast unbound wrapper for slice
in a single line.
Edit: A better way to create fast unbound wrappers is as follows (note that it may not work in some older browsers, but you don't really need to worry about that now - you may always use a shim for browsers which don't support bind
):
var slice = Function.prototype.call.bind(Array.prototype.slice);
This is the same as:
function slice() {
return Function.prototype.call.apply(Array.prototype.slice, arguments);
}
How it works:
Function.prototype.call
is a function.
- The
this
pointer of call
points to Function.prototype
.
- We use
bind
to change the this
pointer of call
to Array.prototype.slice
.
bind
returns a function whose arguments
are applied to call
.
Bonus: If your style of programming is highly functional, like mine is, then you would find that is piece of code is very useful:
var funct = Function.prototype;
var obj = Object.prototype;
var arr = Array.prototype;
var bind = funct.bind;
var unbind = bind.bind(bind);
var call = unbind(funct.call);
var apply = unbind(funct.apply);
var classOf = call(obj.toString);
var ownPropertyOf = call(obj.hasOwnProperty);
var concatenate = call(arr.concat);
var arrayFrom = call(arr.slice);
- Using this you may easily create unbound wrappers using either
call
or apply
.
- You may use
classOf
to get the internal [[Class]]
of a value.
- You may use
ownPropertyOf
inside for in loops.
- You may use
concatenate
to join arrays.
- You may use
arrayFrom
to create arrays.