_.slice(array, [start = 0], [end = array.length])
每天更新一个lodash方法源码解析
slice用于对数组元素进行截取,返回值为截取元素组成的一个新数组。slice方法很容易让人联想到Array.slice(),它是不是对Array.slice()的一层封装?答案是no,lodash自己实现了一个slice方法来替代Array.slice()方法。
官方文档中这句话也证明了,上面的话意思就是:使用该方法(_.slice())来替代Array.slice()以确保返回密集数组。
example:
_.slice([1, 2, 3, 4, 5], 2, 4)
// [3, 4]
_.slice([1, 2, 3, 4, 5])
// [1, 2, 3, 4, 5]
slice(array, [start = 0], [end = array.length])接收3个参数,第一个参数array为原数组,也就是将要截取的元素;第二个参数为start,数组截取开始时的位置,默认为0;第三个参数为截取结束时的位置,默认为原数组的长度,截取时截取的元素是不包含结束位置的元素的。
源码解析:
function slice(array, start, end) {
// 如果array为null,length为0,否则取array.length
let length = array == null ? 0 : array.length
// 如果length为0,则返回空数组
if (!length) {
return []
}
// 判断第二个参数start有没有传值,没有传值则取0,传值则取传入的值
start = start == null ? 0 : start
// 判断第三个参数end有没有传值,没有传值则取array的长度,传值则取传入的值
end = end === undefined ? length : end
// 处理start小于0的情况
// 如果start小于0且-start的值大于array的长度,则start取0,否则start取数组长度加start的值
if (start < 0) {
start = -start > length ? 0 : (length + start)
}
// 当end值大于数组长度时,end取数组的长度
end = end > length ? length : end
// 处理end小于0的情况
// 当end小于0时,end取数组长度加end的值
if (end < 0) {
end += length
}
// 如果start大于end,则length取0,否则取end-start值
// 其中(end-start) >>> 0作用是保证(end-start)是一个有意义的正整数,详细可参考这篇文章:https://segmentfault.com/a/1190000014613703
// 执行下面语句后,length值将变为返回数组的长度
length = start > end ? 0 : ((end - start) >>> 0)
// 确保start为一个有意义的正整数
start >>>= 0
// 定义一个index,后面将作为数组result的索引值
let index = -1
// 定义返回数组result,其长度为length
const result = new Array(length)
// 遍历数组result,并将原数组array中index+start对应的元素添加到result数组中index对应的位置
while (++index < length) {
result[index] = array[index + start]
}
// 返回结果result
return result
}
实现思路:根据start和end参数计算出返回数组的长度,利用返回数组长度生成一个新数组,然后遍历该新数组,并将原数组中index+start对应的值给到新数组index对应的位置。
2019/6/17