本篇分析lodash
的drop
系列方法,包括drop
、dropWhile
、dropRight
、dropRightWhile
引用的私有方法
baseWhile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import slice from '../slice.js'
function baseWhile(array, predicate, isDrop, fromRight) { const { length } = array let index = fromRight ? length : -1
while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {}
return isDrop ? slice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) : slice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)) }
export default baseWhile
|
引用的公开方法
在之前的文章中已经详细的把toInteger
和slice
及其引用的方法都分析过。
toInteger
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| import toFinite from './toFinite.js'
function toInteger(value) { const result = toFinite(value) const remainder = result % 1 return remainder ? result - remainder : result }
export default toInteger
|
slice
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
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
|
drop 系列
drop
系列方法其实就是两个区别,第一个是从左向右还是从右向左,第二个是是否使用n还是predicate来判断。
drop
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import slice from './slice.js' import toInteger from './toInteger.js'
function drop(array, n=1) { const length = array == null ? 0 : array.length return length ? slice(array, n < 0 ? 0 : toInteger(n), length) : [] }
export default drop
|
dropWhile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import baseWhile from './.internal/baseWhile.js'
function dropWhile(array, predicate) { return (array != null && array.length) ? baseWhile(array, predicate, true) : [] }
export default dropWhile
|
dropRight
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import slice from './slice.js' import toInteger from './toInteger.js'
function dropRight(array, n=1) { const length = array == null ? 0 : array.length n = length - toInteger(n) return length ? slice(array, 0, n < 0 ? 0 : n) : [] }
export default dropRight
|
dropRightWhile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import baseWhile from './.internal/baseWhile.js'
function dropRightWhile(array, predicate) { return (array != null && array.length) ? baseWhile(array, predicate, true, true) : [] }
export default dropRightWhile
|
原生实现
原生实现drop
时,其实使用Array.prototype.slice
方法就可以,主要记住三个要点:
slice
方法不改变原数组,返回一个新的数组。
slice
方法返回的新数组中的元素是原数对应元素的浅拷贝
。
slice
方法剪切时包含start
的元素,不包含end
的元素
drop
1 2 3 4 5 6
| [1, 2, 3].slice(1);
[1, 2, 3].slice(2);
|
dropRight
1 2 3 4 5 6
| [1, 2, 3].slice(0, -1);
[1, 2, 3].slice(0, -2);
|