In the Es5 standard, we often need to convert the arguments object into a real array
1 // You can write it like this
2 var arr = Array.prototype.slice.call(arguments)
3
4 // You can write it like this
5 var arr = [].slice.call(arguments)
6
7 // If you are not afraid of trouble, you can also write like this
8 var arr = [].__proto__.slice.call(arguments)
The above three writing methods are equivalent
1 // When you understand the prototype chain, you know
2 Array.prototype === [].__proto__ // true
3
4 // [].slice calls the slice method in the prototype object of the instance[]
5 [].slice === [].__proto__.slice // true
Array.prototype.slice.call (arguments) originally called slice by array.prototype, but call (arguments) changed the object calling slice method to arguments. You can imagine that
Array.prototype.slice.call(arguments) ~ arguments.slice()
Array.prototype.slice.call(arguments, [begin[, end]]) ~ arguments.slice([begin [, end]])
We may think that the arguments prototype object is object. Prototype, and there is no slice method. Where does slice method come from
This is because call (arguments) not only changes the direction of this, but also makes the arguments object inherit the slice method in array. Prototype
The following is the source code of array. Prototype. Slice(): 587 lines of GitHub address
function ArraySlice(start, end) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice");
var array = TO_OBJECT(this);
var len = TO_LENGTH(array.length);
var start_i = TO_INTEGER(start);
var end_i = len;
if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end);
if (start_i < 0) {
start_i += len;
if (start_i < 0) start_i = 0;
} else {
if (start_i > len) start_i = len;
}
if (end_i < 0) {
end_i += len;
if (end_i < 0) end_i = 0;
} else {
if (end_i > len) end_i = len;
}
var result = ArraySpeciesCreate(array, MaxSimple(end_i - start_i, 0));
if (end_i < start_i) return result;
if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) {
%NormalizeElements(array);
if (IS_ARRAY(result)) %NormalizeElements(result);
SparseSlice(array, start_i, end_i - start_i, len, result);
} else {
SimpleSlice(array, start_i, end_i - start_i, len, result);
}
result.length = end_i - start_i;
return result;
}
Arguments can be converted to array objects because
We can see that the member properties of the arguments object are similar to arrays and have the length property. Is it so that similar objects can call slice?Let’s have a test
1 var obj = {
2 0: 'foo',
3 1: 'bar',
4 2: 'arg',
5 length: 3
6 }
7 console.log(Array.prototype.slice.call(obj))
8 // ["foo", "bar", "arg"]
This is OK
*PS: ES6 syntax adds array. From (), so the above types of objects can be directly converted into arrays by array. From (obj)