A: Why lodash slice

JavaScript Array already has a slice method, so why do we need to re-implement it multiple times? There is a comment above the source code

This method is used instead of Array#slice to ensure dense arrays are returned

Dense Arrays is dense arrays with content, not empty arrays with no content. Take a look at an example of native Slice arrays:

var a = new Array(3)
var b = a.slice()
console.log(b); // [ <3 empty items> ]
b.forEach((el) = > {
  console.log('b item:',el)
})
Copy the code

In the above example, we created an array with length 3 and put it into B with slice cutting. Then we printed B and returned [<3 Empty items>]. This is a length but no content array. It doesn’t sound good, but let’s call it English. Sparse Array is not iterated as the contents of B are not executed.

Let’s look at an example of slicing an array with LoDash slice:

var a = new Array(3)
var b = slice(a)
console.log(b); // [ undefined, undefined, undefined ]
b.forEach((el) = > {
  console.log('b item:',el)
})
var c = b.map(function (x, i) {
  return i;
});
console.log(c) / / / (0, 1, 2);
Copy the code

The LoDash slice returns a dense array, which is a dense array with both length and content. When we iterate over the array, we see that the whole thing is working. What are the benefits of using a Dense Array? The Dense Array is convenient when an empty array is generated to iterate over new empty options.

How to ensure that the value returned is correct?

So let’s do a little demo

console.log(slice([1.2.3.4] and {}));Copy the code

This example returns an empty array, but it does not return an error. Let’s simplify the source code

function slice(array, start, end) {
  let length = array == null ? 0 : array.length;
  if(! length) {return [];
  }
  start = start == null ? 0 : start; // start = {}
  end = end === undefined ? length : end; // end = length
  end = end > length ? length : end; // end = length
  length = start > end ? 0 : (end - start) >>> 0; //length = 0
  start >>>= 0;  // start = 0

  let index = -1;
  const result = new Array(length); // result = []
  while (++index < length) {
    result[index] = array[index + start];
  }
  return result;
}
Copy the code

The secret is to use >>>. This symbol is called the unsigned right shift operator. >>>0 ensures that the value is a meaningful positive integer, and defaults to 0 if it is not. Here {}>>>0 is converted to 0, so no error is reported.

Let’s do another demo

console.log(slice([1.2.3.4])); // [1, 2, 3, 4]
Copy the code

In this example we give no start value, no error, and return the full array. How does this work? There is such a sentence in the source

start = start == null ? 0 : start
Copy the code

Start = undefined One of the rules for the binary operator == is used here, null == undefined.

References:

JavaScript: sparse arrays vs. dense arrays

Lodash source