First, explain []. slice.call() and Array.prototype.slice.call() What's the difference?
[].slice === Array.prototype.slice true
[] to create an array, when []. slice, it will naturally find the prototype chain
[].__proto__.slice === Array.prototype.slice true
Array.prototype.slice is a defined method that can be overridden
[]. silce is a method defined using
- Its own attributes are different (because the prototype is different from [])
Object.getOwnPropertyNames(Array.prototype) (37) ["length", "constructor", "concat", "pop", "push", "shift", "unshift", "slice", "splice", "includes", "indexOf", "keys", "entries", "forEach", "filter", "map", "every", "some", "reduce", "reduceRight", "toString", "toLocaleString", "join", "reverse", "sort", "lastIndexOf", "copyWithin", "find", "findIndex", "fill", "remove", "removeFirstIf", "removeIf", "repeat", "last", "lastDef", "clone"] Object.getOwnPropertyNames([]) ["length"]
Therefore, there is no essential difference between [] and Array.prototype in essence, but there is a difference in calling, but according to professional detection, [] should be faster
The explanation of slice on MDN is
slice() method returns a part of the array selected from the beginning to the end (excluding the end) for shallow copy to a new array object, and the original object will not be modified
var animals = ['ant', 'bison', 'camel', 'duck', 'elephant']; console.log(animals.slice(2)); // expected output: Array ["camel", "duck", "elephant"] console.log(animals.slice(2, 4)); // expected output: Array ["camel", "duck"] console.log(animals.slice(1, 5)); // expected output: Array ["bison", "camel", "duck", "elephant"]
The parameter has two slices (begin, end)
begin :- If there are no parameters, start with 0
- If yes, it comes from the index (the first digit is 0)
- If the parameter is negative, it means to extract from the penultimate element in the original array, and slice(-2) means to extract from the penultimate element to the last element (including the last element) in the original array
- If there is no parameter, it is taken to the end of the array by default
- If it is greater than the length of the array, it is taken to the end of the array
- slice(1,4) Extract all elements from the second element to the fourth element in the original array (elements with indexes of 1, 2 and 3)
- If the parameter is negative, It indicates that the penultimate element in the original array ends the extraction.
var a = [1,2,3,4,5,6,7,8]; a.slice(3,-2) (3) [4, 5, 6]Return value
A new array containing extracted elements
slice Without modifying the original array, only a new array with shallow copy of the elements in the original array will be returned.
-
If the element is an object reference (not an actual object), slice This object reference will be copied to the new array. Both object references refer to the same object. If the referenced object changes, the element in the new and original array will also change.
-
For strings, numbers, and Booleans (not String,Number perhaps Boolean Object), slice These values will be copied to the new array. Modifying these strings or numbers or boolean values in another array will not affect the other array.
If you add a new element to either array, the other is not affected.
The above is the professional explanation of slice in MDN
slice This method returns when it does not accept any parameters this itself
arguments It is a variable within a function whose value is the function parameter list. An array like object has a length attribute, but it is not an array. It does not have the slice () method, which means arguments.slice() doesn't work
Here, the call of this can be changed. What happens if I use call to give arguments to slice?
slice will get the object with the length attribute, which realizes the conversion of the object to an array
function list() { return Array.prototype.slice.call(arguments); } console.log(list(1, 2, 3));
Some people will ask why the call of arguments to slice can be turned into an array. What happened inside
We can implement our own slice(), and we'll see
Myslice()
Array.prototype.Myslice = function (begin,end){ var start = begin || 0; //judge begin Time existence or nonexistence give 0 here judgment can be strengthened var len = this; //obtain this.length I got it here call Who came in start = (start >= 0) ? start : Math.max(0, len + start); //Judge whether the parameter is greater than 1,In the case of negative numbers begin Value end = (typeof end == 'number') ? Math.min(end, len) : len; //judge end Is it greater than this.length Length of if(end<0){ end = end + len //Judge the situation of negative value } var result = new Array(); for (let i = 0; i < end.length; i++) { result.push(this[i]) } return result; } function list() { return Array.prototype.Myslice.call(arguments); } console.log(list(1, 2, 3));
I believe you can understand why Array.prototype.slice.call turns objects into arrays~~~
Finally, paste the source code of JavaScript sclie
Array.prototype.slice = function(begin, end) { end = typeof end !== 'undefined' ? end : this.length if (Object.prototype.toString.call(this) === '[object Array]') { return _slice.call(this, begin, end) } var i, cloned = [], size, len = this.length var start = begin || 0 start = start >= 0 ? start : Math.max(0, len + start) var upTo = typeof end == 'number' ? Math.min(end, len) : len if (end < 0) { upTo = len + end } size = upTo - start if (size > 0) { cloned = new Array(size) if (this.charAt) { for (i = 0; i < size; i++) { cloned[i] = this.charAt(start + i) } } else { for (i = 0; i < size; i++) { cloned[i] = this[start + i] } } } return cloned } function list() { return Array.prototype.slice.call(arguments) } console.log(list(1, 2, 3))