You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
letarr=[-1,-3,-6,0,3,6,9]letobj={sex: 'boy',name: 'qianlongo'}letresult=_.find(arr,(val,key,arr)=>{returnval>0})// 3letresult2=_.find(obj,(val,key,obj)=>{returnval.indexOf('o')>-1})// boy
functioncreateReduce(dir){// Optimized iterator function as using arguments.length// in the main function will deoptimize the, see #1991.functioniterator(obj,iteratee,memo,keys,index,length){// 真正执行迭代的地方for(;index>=0&&index<length;index+=dir){varcurrentKey=keys ? keys[index] : index;// 如果keys存在则认为是obj形式的参数,所以读取keys中的属性值,否则类数组只需要读取索引index即可memo=iteratee(memo,obj[currentKey],currentKey,obj);// 接着就是执行外部传入的回调了,并将结果赋值为memo,也就是我们最后要到的值}returnmemo;}returnfunction(obj,iteratee,memo,context){iteratee=optimizeCb(iteratee,context,4);// 首先绑定一下this作用域varkeys=!isArrayLike(obj)&&_.keys(obj),// 如果不是类数组就读取其keyslength=(keys||obj).length,index=dir>0 ? 0 : length-1;// 默认开始迭代的位置,从左边第一个开始还是右边第一个// Determine the initial value if none is provided.if(arguments.length<3){// 如果没有传入初始化值,则将第一个值(左边第一个或者右边第一个)作为初始值memo=obj[keys ? keys[index] : index];index+=dir;// 从索引为1开始或者索引为length - 2开始迭代}returniterator(obj,iteratee,memo,keys,index,length);// 接着开始进入自定义的迭代函数,请往上看};}
前言
underscore.js源码分析第三篇,前两篇地址分别是
那些不起眼的小工具?
(void 0)与undefined之间的小九九
本篇原文链接
源码地址
从步入程序猿这个大坑开始到现在,已经看过数不清的技术文章和书籍,有的是零散的知识,有的是系列权威的教程,但为毛还写不好挚爱的前端,听说过一句话,这个世界又不是只有你一个人深爱而不得。但纵使如此,我也要技术这条路上一路走到黑。直到天涯迷了路,海角翻了船。
开始
接下来我们从下划线underscore.js的视角,一步步看他们的内部运行的原理是什么....
1 _.each(list, iteratee, [context])
先来看一下怎么使用
可以看出下划线的each和原生的数组forEach有些类似也有不同的地方
原生的forEach只可以遍历数组,而下划线的each还可以遍历对象。接下来你想不想一起看下下划线是怎么实现的。come on!!!
源码
😉,其实也没有那么难理解是吧!开始map函数之旅吧
2 _.map(list, iteratee, [context])
使用案例
当然还可以传入第三个参数context,其本质如each一般,也是让iteratee函数中的this动态设置为context
源码
通过源码可以看到map的实现思路
3 _.every(list, [predicate], [context])
使用案例
使用起来蛮简单的,传入一个谓词函数(返回值是一个布尔值的函数),最后得到true或者false。
源码
4 _.some(list, [predicate], [context])
使用案例
源码中是怎么实现的呢,与every唯一不同的地方在返回
true
还是falase
之处?源码
5 _.find(list, predicate, [context])
使用案例
源码
_.findIndex
和_.findKey
在后面会一一分析,目前理解find函数知道他们怎么用就好。6 _.filter(list, predicate, [context])
使用案例
聪明的你是不是已经想到了源码是怎么实现的了 😉
源码
最后是reduce和reduceRight,两个相对来说更难一些的api,虽然已经过了12点了,手动困乏😪, 我们咬咬牙坚持一下,把最后两个说完
7 _.reduce(list, iteratee, [memo], [context]),
8 _.reduceRight(list, iteratee, memo, [context])
使用案例
我们来看一下上面的执行过程是怎样的。
第一回合
第二回合
第三回合
第四回合
第五回合
😭妈妈啊,终于执行完了,这么多回合才结束,哪像人家格斗高手瞬间就把太极大师整挂了
知道了一步步执行流程,我们来看下源码到底是怎么实现的。
源码
这尼玛看起来好吓人啊,不怕,我们一点点来分析
结语
不介意的话,在文章开头的源码地址那里点一个小星星吧😀
不介意的话,在文章开头的源码地址那里点一个小星星吧😀
不介意的话,在文章开头的源码地址那里点一个小星星吧😀
The text was updated successfully, but these errors were encountered: