简体   繁体   中英

Prototype in this Array slice call, why?

I was reading the MDN page for the JS Function's arguments variable:

https://developer.mozilla.org/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?

Why 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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM