前言
underscore.js源码分析第三篇,前两篇地址分别是
😔看了很多篇技术文章,却依然写不好前端。
从步入程序猿这个大坑开始到现在,已经看过数不清的技术文章和书籍,有的是零散的知识,有的是系列权威的教程,但为毛还写不好挚爱的前端,听说过一句话,这个世界又不是只有你一个人深爱而不得。但纵使如此,我也要技术这条路上一路走到黑。直到天涯迷了路,海角翻了船。
开始
今天想说几个类似我们平常的工作中经常用到的几个宝贝,姑且把他叫做杀手锏好了,因为实在是特别好用呀,他们分别是…
- each
- map
- reduce
- reduceRight
- find
- filter
- every
- some
接下来我们从下划线underscore.js的视角,一步步看他们的内部运行的原理是什么….
1 _.each(list, iteratee, [context])
遍历list中的所有元素,按顺序用遍历输出每个元素,如果传递了context,则将iteratee函数中的this绑定到context上。
先来看一下怎么使用
|
|
可以看出下划线的each和原生的数组forEach有些类似也有不同的地方
原生的forEach只可以遍历数组,而下划线的each还可以遍历对象。接下来你想不想一起看下下划线是怎么实现的。come on!!!
源码
|
|
😉,其实也没有那么难理解是吧!开始map函数之旅吧
2 _.map(list, iteratee, [context])
通过iteratee将list中的每个值映射到一个新的数组中(注:产生一个新的数组。y = f(x),类似高中学过的知识,将x通过f()映射为一个新的数
使用案例
|
|
当然还可以传入第三个参数context,其本质如each一般,也是让iteratee函数中的this动态设置为context
源码
|
|
通过源码可以看到map的实现思路
- 创建一个即将返回的数组
- 遍历list(可以为数组也可以为对象),将list的元素输入到传进来的iteratee函数中,并将其执行后的返回值填充进数组。这个iteratee负责映射规则
3 _.every(list, [predicate], [context])
当list中的所有的元素都可以通过predicate的检测,那么结果返回true,否则false
使用案例
|
|
使用起来蛮简单的,传入一个谓词函数(返回值是一个布尔值的函数),最后得到true或者false。
源码
|
|
4 _.some(list, [predicate], [context])
如果list中有任何一个元素通过 predicate的检测就返回true。否则返回false,和every恰好有点相反的意思。
使用案例
|
|
源码中是怎么实现的呢,与every唯一不同的地方在返回true
还是falase
之处?
源码
|
|
5 _.find(list, predicate, [context])
遍历list中的元素,返回第一个通过predicate函数检测的值。
使用案例
|
|
源码
|
|
_.findIndex
和_.findKey
在后面会一一分析,目前理解find函数知道他们怎么用就好。
6 _.filter(list, predicate, [context])
遍历list,返回包含所有通过predicate检测的元素(结果是个数组)
使用案例
|
|
聪明的你是不是已经想到了源码是怎么实现的了 😉
源码
|
|
最后是reduce和reduceRight,两个相对来说更难一些的api,虽然已经过了12点了,手动困乏😪, 我们咬咬牙坚持一下,把最后两个说完
7 _.reduce(list, iteratee, [memo], [context]),
别名为 inject 和 foldl, reduce方法把list中元素归结为一个单独的数值。Memo是reduce函数的初始值,reduce的每一步都需要由iteratee返回。这个迭代传递4个参数:memo, value 和 迭代的index(或者 key)和最后一个引用的整个 list
8 _.reduceRight(list, iteratee, memo, [context])
reducRight是从右侧开始组合的元素的reduce函数
使用案例
|
|
我们来看一下上面的执行过程是怎样的。
第一回合
|
|
第二回合
|
|
第三回合
|
|
第四回合
|
|
第五回合
|
|
😭妈妈啊,终于执行完了,这么多回合才结束,哪像人家格斗高手瞬间就把太极大师整挂了
知道了一步步执行流程,我们来看下源码到底是怎么实现的。
源码
|
|
这尼玛看起来好吓人啊,不怕,我们一点点来分析
|
|
结语
夜深人静,有点困乏了。希望这篇文章对大家有点作用。如果对前几篇源码分析的文章感兴趣,欢迎前往顶部地址查看
不介意的话,在文章开头的源码地址那里点一个小星星吧😀
不介意的话,在文章开头的源码地址那里点一个小星星吧😀
不介意的话,在文章开头的源码地址那里点一个小星星吧😀