I was reading the MDN page for the JS Function's arguments variable:
I understand that arguments is not an Array so this won't work:
var a = arguments.slice();
The solution on MDN is do do this:
var args = Array.prototype.slice.call(arguments);
Why use Array.prototype
and not just Array.slice.call(arguments)
? Is using the prototype significant here?
I was reading the MDN page for the JS Function's arguments variable:
https://developer.mozilla/en/JavaScript/Reference/Functions_and_function_scope/arguments
I understand that arguments is not an Array so this won't work:
var a = arguments.slice();
The solution on MDN is do do this:
var args = Array.prototype.slice.call(arguments);
Why use Array.prototype
and not just Array.slice.call(arguments)
? Is using the prototype significant here?
5 Answers
Reset to default 7Why use Array.prototype and not just Array.slice.call(arguments)?
The Array.slice
method is part of the Array and String Generics, a set of "static" methods implemented as properties of the Array
and String
constructors.
Those methods are non-standard, they are available just in Mozilla-based implementations.
I've seen a lot confusion between those methods and the standard ones, but you should know that they aren't the same, if you test:
Array.slice === Array.prototype.slice; // false
You will find that they are different methods.
And by the way, if you where using that method, you don't need to use the call
method, the first argument is the object that will be used as the this
value (Array.slice(arguments)
).
Is using the prototype significant here?
Yes, the Array
constructor is just a function, the standard slice
method, and all the other "array methods" are defined on Array.prototype
.
This object, Array.prototype
, is the one in which all Array object instances inherit from.
As @Pointy says, you could get a reference to the method using an Array instance:
[].slice === Array.prototype.slice; // true
This, in theory, will create a new Array object, and access the slice
method up in the prototype chain, but I remember that some implementations are starting to optimize this kind of property access, avoiding the creation of the disposable object, so, at some point, it will be exactly the same also talking in terms of performance.
It should be noted that:
var argslice = [].slice.call(arguments);
works too, because if "slice" is a reference to a function on the prototype for the Array constructor then "slice" on a constructed array is (therefore) that very same function.
Array.slice
doesn't exist (at least not in chrome).
slice
is part of the prototype for Array
objects, not a method on Array
itself, so to reference it you need to go through the prototype.
prototype contains all functions available on "Array" objects. Array itself only refers to the constructor. Therefore you have to get the function from the prototypes and apply it to the pseudo array "arguments".
Short answer: yes, the prototype
is significant.
slice
is a property of the Array object's prototype
object. If Array.slice
were to exist, it would be a property of the Array constructor function.
For example, when you write:
function MyConstructor() {
..
}
MyConstructor.someFunc = function() {
..
}
someFunc is a property of the MyConstructor function object so this won't work:
var obj = new MyConstructor();
obj.someFunc(); // Throws error
But this will:
MyConstructor.someFunc();
If you want to have properties available on all instances, you must add them to the prototype
object of your constructor. For example:
MyConstructor.prototype.someFunc = function() {
..
};
Which would allow you to do this:
var obj = new MyConstructor();
obj.someFunc();