百忙之中(閒來無事)想抽點時間好好讀一下源碼,因而就選了Lodash來寫一個系列罷。讀源碼順序就按照loadsh文檔順序來。javascript
第一個函數是chunk
,不過源碼中chunk
依賴了slice
,因此第一篇文章就從slice
開始。java
_.slice(array, [start=0], [end=array.length])
這個函數的做用就是裁剪數組array,從start下標開始,到end下標結束,可是並不包含end,並將結果做爲一個數組返回。而且註明了:git
Note: 這個方法用於代替 Array#slice 來確保數組正確返回。
看起來和原生javascript的slice沒有區別,那爲何要重寫這個函數呢?有如下幾個緣由:github
下面咱們來看一下具體的實現,一行行來看代碼:數組
首先是數組array是否合法的判斷:jsp
let length = array == null ? 0 : array.length if (!length) { return [] }
開始位置start
和結束位置end
默認值:函數
start = start == null ? 0 : start end = end === undefined ? length : end
支持負數start
,以及start
合法性檢測:超出數組長度即爲0,不然從右往左數測試
if (start < 0) { start = -start > length ? 0 : (length + start) }
end
合法性檢測:超出數組長度即爲數組長度
若是end
爲負數,則從右往左數spa
end = end > length ? length : end if (end < 0) { end += length }
數組裁剪後的長度,這裏爲了速度因此使用了>>>
來向下取整
start向下取整
length = start > end ? 0 : ((end - start) >>> 0) start >>>= 0
經過循環來淺拷貝數組的元素,最終返回
let index = -1 const result = new Array(length) while (++index < length) { result[index] = array[index + start] } return result
最後貼個源碼:
/** * Creates a slice of `array` from `start` up to, but not including, `end`. * * **Note:** This method is used instead of * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are * returned. * * @since 3.0.0 * @category Array * @param {Array} array The array to slice. * @param {number} [start=0] The start position. A negative index will be treated as an offset from the end. * @param {number} [end=array.length] The end position. A negative index will be treated as an offset from the end. * @returns {Array} Returns the slice of `array`. */ function slice(array, start, end) { let length = array == null ? 0 : array.length if (!length) { return [] } start = start == null ? 0 : start end = end === undefined ? length : end if (start < 0) { start = -start > length ? 0 : (length + start) } end = end > length ? length : end if (end < 0) { end += length } length = start > end ? 0 : ((end - start) >>> 0) start >>>= 0 let index = -1 const result = new Array(length) while (++index < length) { result[index] = array[index + start] } return result } export default slice