源码学习——lodash(十)

前言

上节介绍了三种方法,有些方法lodash会直接用原生的,本节我们来学习一下take系列方法的源码。

take与takeRight

take从数组中的起始位置开始提取n个元素,返回提取元素组成的数组,该方法不会修改原数组。

js 复制代码
_.take(array,n)
//n为提取的个数,默认为1
console.log(_.take([1,2])) //[1]

该方法也很简单,我们先自己实现一下:

思路很简单判断下array与n,然后获取提取个数count,最后用while循环赋值。接下来我们来看下lodash的处理:

  • array进行非空判断。
  • 通过slice方法进行提取,这里对n小于0的情况了判断。
    slice方法上节我们也提到了,当时熟悉了一下源码,本节我们不再赘述。slice截取数组数据的方法用的很广,相关源码我们还是要熟悉的。
    takeRight从数组的最后位置开始提取n个元素,该方法就是从右开始上面我们自己写的方法,把下标换一下就可以了。
js 复制代码
_.takeRight(array,n)
console.log(_.takeRight([1,2])) //[2]

slice方法中没有right相关参数,不过start可以为负数能达到从右开始的效果。下面我们来看下lodash的实现方法:

  • 非空判断,将n赋值为数组长度减n
  • 利用slice方法提取,start为n,end为length。
    该方法比预测的更加简便,这样提取出来的数据顺序跟原数组是一样的。
js 复制代码
console.log(_.takeRight([1,2,3],2)) //[2,3]

如果较真一点,上面案例结果应该是[3,2],我们可以在此结果的基础上加上个reverse。

takeWhile与takeRightWhile

takeWhile跟take效果一样,不过第二个参数从n变为了函数,当元素值不满足迭代函数时停止提取。

js 复制代码
_.takeRWhile(array,predicate)
// predicate 迭代的函数 value index array三个参数
console.log(_.takeWhile([1,2,3],(item)=>item<3)) //[1,2]

该方法肯定不会再用slice方法了,具体的源码如下:

  • 利用三目运算对array进行非空判断,为true时执行baseWhile 获取结果。
    takeRightWhile从未位开始提取,返回提取的数组。该方法参数跟takeWhile一样:
js 复制代码
console.log(_.takeRightWhile([1,2,3],(item)=>item>1)) //[2,3]

源码就是baseWhile多了两个参数,false与true。接下来我们就来研究下baseWhile的代码。

首先我们先来看下baseWhile的四个参数:

array:数组,必传参数。

predicate:迭代函数。

isDrop:是否丢弃,与提取相反。如果为true会将符合条件的元素去掉。

fromRight:布尔值,为true时从右边开始提取。

上述参数中需要注意isDrop参数,要想达到take效果该参数必须为false,这就是takeRightWhile第三个为false的原因。下面我们进入代码分析:

  • 获取数组length,声明下标index,fromRight为true从右开始index的值为length;为false就为-1。
  • 利用while循环数组,得到数组中predicate为true的元素。该条件利用&&,兼容了从右开始的情况而且简化了写法,比if简便的多。
  • 最终通过slice得到结果,此步重点是start与end的取值,这里源码显得复杂点,我们从方法角度进行分解就清晰了:
js 复制代码
slice(array,0,index) // takeWhile
slice(array,index+1,length) // takeRightWhile

slice(array,0,index+1) // !takeRihgtWhile
slice(array,index,length) // !takeWhile

把上面四个用方法合到一起就得到了源码。只要我们知道方法效果化繁为简,源码还是很好理解的。

总结

以上就是take系列方法的源码,都是基于slice方法实现的,这节我们又学到一个基础方法basewhile。

相关推荐
腾讯TNTWeb前端团队1 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪5 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom6 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom6 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom6 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom6 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom6 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试