前言原文链接源码地址今天想写一篇关于underscore库的一些实用小函数的故事。我们都听过这样一句话,成功男人的背后一定有一个伟大的女人(?,其实不一定,也许还有男人),那么一个长盛不衰、被程序员称赞的库,自然有很多“小玩意儿””在看似不起眼的框架后面,你甚至都懒得看他一眼。正是这些背后的无名英雄,为类库和框架的形成做出了不可磨灭的贡献。第一篇说undefined,那我们先说undefined。_.isUndefined(obj)判断obj是否等于undefined,如果是则返回true,否则返回false。例子leta=nullletb=window.bletc=()=>{}letd=undefinedlete=void0letf='qianlongo'letgconsole.log(_.isUndefined(a))//falseconsole.log(_.isUndefined(b))//trueconsole.log(_.isUndefined(c()))//trueconsole.log(_.isUndefined(d))//trueconsole.log(_.isUndefined(e))//trueconsole.log(_.isUndefined(f))//falseconsole.log(_.isUndefined(g))//对于对象上不存在的属性为真对于不返回标量值的函数declaredandnotassignedavalue直接赋值给undefined(不在ie8以下)或者void0_.isUndefined会返回true,其他情况都会返回false。需要注意的是,有时候我们判断一个变量是否存在,a=nulla=undefined可以通过Sad来判断。if(a==null){}但是_.isUndefined使用了三级强制判断,所以null不能通过_.isUndefined=function(obj){returnobj===void0;}_.isNull(obj)来判断obj是否等于null,如果是则返回true,否则返回false。这个没什么好说的,只有obj输入null,result输出才会为true,因为内部判断也是三级判断,不仅value要相等,type也要一样。_.noConflict()是防止全局变量冲突的常用方案,将_的使用权交换给最后一个占_坑的人。示例console.log(_)遇到同名应该不陌生吧?全国有多少小明?啊,我们小时候课本上到处都是小明和小红。这里后面介绍的underscore.js覆盖了lodash.js,因为两个库都想占全局_,结果就是后来者占上风。如果你不想lodash被覆盖怎么办,总是先到先得。只需调用noConflict方法将占用的_坑返回给lodash,然后我们就可以使用my_来访问underscore.js的所有方法了。letmy_=_.noConflict()接下来看看源码是如何实现的varpreviousUnderscore=_//源码最上面,保存了之前占_坑的人_.noConflict=function(){root._=previousUnderscore;//将_重新赋值给之前占用_坑的人returnthis;//andreturn_以供后续使用};_.identity(value)返回与传入的参数值相同的值这个函数貌似用处不大,但是以后可以起到很重要的作用,这也体现了工具虽小,威力却很大。先简单看一下它的应用,在后续的源码分析中遇到。仔细解释。过滤“真”值数组letarr=['a','b',null,'false',0,'c','',false,{}]letarr2=arr.filter(_.identity)//["a","b","false","c",{}]复制数组letarr=['a','b',null,'false',0,'c','',false,{}]letarr2=arr.map(_.identity)//["a","b",null,"false",0,"c","",false,{}]_.constant(value)返回一个函数fn,fn执行后,返回一开始传入的值看看github上一个关于下划线的issue,挺有意思的。或许我们很难一一列举这个函数的应用,但至少下面这个例子比较好。letage=18letcacheAge=_.constant(age)age+=10console.log(cacheAge())//为什么18可以缓存18?看看源码就知道了。源码创建了一个通用的闭包,closure包的一个通用功能是允许外部通过函数调用访问内部变量,并缓存一定生命周期内的变量。_.constant=function(value){returnfunction(){返回值;};};_.noop()是一个什么都不做的空函数,调用后返回undefined给你,可以作为默认的回调参数是一个看似没什么用的函数,但真的是这样吗?请移步以下链接jQuery.noop()函数有什么用?无操作的JavaScript约定是什么?例子不多,总结一下1.给一个空函数赋值一个变量,在后面的调用中不需要去检查他是否是undefined2.为什么不将空函数重置为所需变量?_.noop创建了一个函数空间,允许其他变量指向这个函数,可以减少js中不必要的开销indexvalueindex,最后返回一个数组,里面存放的是这些iterationes的回调结果。示例letcount=0letresult=_.times(6,(i)=>{console.log(++count)return`hello:${i}`})console.log(result)//["hello:0","hello:1","hello:2","hello:3","hello:4","hello:5"]console.log(count)//6可以看到传入的函数已经执行了6次,每次执行对应的结果会存储在一个数组中返回。_.random(min,max)返回[min,max]之间的随机整数。如果不传递max,间隔为[0,min]random=function(min,max){if(max==null){//如果只有一个参数max=min;//把第一个参数设为最大值min=0;//0作为最小值}returnmin+Math.floor(Math.random()*(max-min+1));//想象一下,我们要求[4,10)//(min)是保证最小值可以取到4//(max-min+1)=>(10-4+1)=>7//Math.random()*7=>[0,1)*7=>[0,7)//Math.floor([0,7))=>最小为0,最大为6//最后变成4+[0,6]=>[4,10]};当然,如果你传入一个非整数,或者一个max
