每日源码分析 - lodash(slice.js)

本文解析了 Lodash 中的 slice 函数实现细节,包括参数校验、逻辑处理及新数组构建过程。此函数用于从指定起始和结束位置深拷贝原数组的一部分到新数组。

本系列使用 lodash 4.17.4版本

一、源码示例


/**
 * 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.
 * @param {number} [end=array.length] The end position.
 * @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
}

var ret = slice(['1','2','3','4'],1,3)

console.log(ret)
复制代码

二、函数作用


上述示例代码的结果是:

[ '2', '3' ]
[Finished in 1.0s]
复制代码

大家从结果可以看出来,这个函数跟js里封装的slice函数是一样的作用,slice(array, star, end),通过传入一个数组,从数组中指定一个开始位置,一个结束位置作为索引,深拷贝数组的一部分到新的数组,通常用来截取数组的子数组。

三、函数工作原理


  1. 判断参数合法性。

(1)判断数组是否为空:

let length = array == null ? 0 : array.length
if (!length) {
    return []
  }
复制代码

(2)判断参数start的合法性: * 判断参数 start 是否为空,若为空,则取0; * 如果 start > 0,按正序取数组片段,若 start < 0,则从右到左算起;

start = start == null ? 0 : start
if (start < 0) {
    start = -start > length ? 0 : (length + start)
}
复制代码

(3)判断参数 end 的合法性: * 判断参数 end 是否为空,若为空,则取length; * 判断参数 end 是否超出数组长度,若超出,则取 length; * 如果 end > 0,按正序取数组片段,若 end < 0,则从右到左算起;

end = end === undefined ? length : end
end = end > length ? length : end
if (end < 0) {
    end += length
}
复制代码

(4)判断参数 start 和 end 的逻辑合法性: * 若end 大于等于 start,则 length 取(end - start),即新数组长度;否则,length = 0,返回空数组; * 将参数 start 和 end 转换为十进制数;

length = start > end ? 0 : ((end - start) >>> 0)
start >>>= 0
复制代码
  1. 截取新数组,返回结果。

(1)创建一个新数组 result,长度为length;

(2)读取数组 array 中位置为 start 到 end 的元素,存到新数组 result 中;

(3)返回新数组 result;

let index = -1
const result = new Array(length)
while (++index < length) {
    result[index] = array[index + start]
}
return result
复制代码

本文章来源于午安煎饼计划Web组 - 初见

相关链接:

每日源码分析-Lodash(castArray.js)

每日源码分析-Lodash(after.js)

每日源码分析-Lodash(chunk.js

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值