Reputation: 16232
In this article, John Resig discusses this snippet for currying:
Function.prototype.curry = function() {
var fn = this, args = Array.prototype.slice.call(arguments);
return function() {
return fn.apply(this, args.concat(
Array.prototype.slice.call(arguments)));
};
};
I am confused about the expression Array.prototype.slice.call(arguments)
.
Here "arguments" is the "this" argument to Array's slice() method, but "slice()" requires an argument itself, so I would think you'd need to do something like Array.prototype.slice.call(arguments, <someIndex>)
. I don't understand how that code can be working as is.
According to the docs on "arguments", "arguments" is not actually an Array, but only an array like object. How are we calling "slice()" on it? And if I put in the code console.log(arguments.slice())
I get an error saying that the object does not have a slice method.
What's going on here?
Upvotes: 1
Views: 79
Reputation: 71939
Answer to first question:
If you call slice on an array without arguments, it will just return a copy of the array. Array.prototype.slice.call(arguments)
does just the same, but operates on the arguments
object, returning an array.
Answer to second question:
We can call slice on arguments
because it's a "generic" method (see the note here). When you pass the arguments
object as this
, slice
will treat it as an array. Since arguments
is an array-like object that contains a length
property, it just works.
Upvotes: 4
Reputation: 413826
The argument to .slice()
is optional. If it's absent, the function just returns a copy of the original array (or array-like object).
The .slice()
function just cares about the presence of a "length" property on the this
object. Thus, because "arguments" does have a "length" property, .slice()
is happy.
Upvotes: 3