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