[]. slice.call understanding

[]. slice.call understanding

 

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

  1. 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

end :

  • 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))

 

Tags: Javascript

Posted on Mon, 22 Nov 2021 11:21:33 -0500 by spamoom