当前位置: 首页 > 后端技术 > Node.js

Lodash学习笔记-一些基本功能(一)

时间:2023-04-03 18:12:20 Node.js

很忙(无事可做)想抽点时间看看源码,所以选择了Lodash来写一个系列。写了几个笔记后,发现很多函数都严重依赖内部的基础函数,一下子看完有点麻烦,于是决定从基础函数入手(不依赖或很少依赖其他函数).文档地址:中文文档英文文档源码地址:gayhubbaseGetTagbaseGetTag,判断变量类型。因为typeof无法处理newNumber(1)的情况,所以lodash重写了类型判断。javascript秘密花园也提到,JavaScript标准库推荐使用Object.prototype.toString.call(value)来判断类型,但是lodash显然做的更多。前半部分是推荐的方法,后半部分在视觉上针对Symbol类型进行了优化,具体步骤有待研究。欢迎有了解的同学告诉我。constobjectProto=Object.prototypeconsthasOwnProperty=objectProto.hasOwnPropertyconsttoString=objectProto.toStringconstsymToStringTag=typeofSymbol!='undefined'?Symbol.toStringTag:undefinedfunctionbaseGetTag(value){if(value==null){返回值===undefined?'[objectUndefined]':'[objectNull]'}if(!(symToStringTag&&symToStringTaginObject(value))){returntoString.call(value)}constisOwn=hasOwnProperty.call(value,symToStringTag)常量标签=value[symToStringTag]letunmasked=falsetry{value[symToStringTag]=undefinedunmasked=true}catch(e){}constresult=toString.call(value)if(unmasked){if(isOwn){值[symToStringTag]=tag}else{deletevalue[symToStringTag]}}returnresult}exportdefaultbaseGetTaggetTaggetTag是在baseGetTag基础上的包,主要是为了兼顾IE11中的数据视图、地图、集合、弱地图和当Node.js<6时的承诺,这一点在源码注解中已经有体现importbaseGetTagfrom'./baseGetTag.js'/**`Object#toString`结果参考。*/constdataViewTag='[objectDataView]'constmapTag='[objectMap]'constobjectTag='[objectObject]'constpromiseTag='[objectPromise]'constsetTag='[objectSet]'constweakMapTag='[objectWeakMap]'/**用于检测映射、集合和弱映射。*/constdataViewCtorString=`${DataView}`constmapCtorString=`${Map}`constpromiseCtorString=`${Promise}`constsetCtorString=`${Set}`constweakMapCtorString=`${WeakMap}`letgetTag=baseGetTag//IE11中数据视图、映射、集合和弱映射的回退和Node.js<6.if((DataView&&getTag(newDataView(newArrayBuffer(1)))!=dataViewTag)中的承诺||(getTag(newMap)!=mapTag)||(getTag(Promise.resolve())!=promiseTag)||(getTag(newSet)!=setTag)||(getTag(newWeakMap)!=weakMapTag)){getTag=(值)=>{constresult=baseGetTag(value)constCtor=result==objectTag?value.constructor:undefinedconstctorString=Ctor?`${Ctor}`:''if(ctorString){switch(ctorString){casedataViewCtorString:returndataViewTagcasemapCtorString:returnmapTagcasepromiseCtorString:returnpromiseTagcasesetCtorString:returnsetTagcaseweakMapCtorString:returnweakMapTag}}返回结果}}exportdefaultgetTagisObjectLikeisObjectLike,判断是否为对象函数isoftvalue'{==obturvalue''&&value!==null}exportdefaultisObjectLikeisArgumentsisArguments调用getTag和isObjectLike判断参数是否为Arguments对象importgetTagfrom'./.internal/getTag.js'importisObjectLikefrom'./isObjectLike'functionisArguments(value){returnisObjectLike(value)&&getTag(value)=='[objectArguments]'}exportdefaultisArgumentssisFlattenableisFlattenable调用isArguments判断是Arguments对象还是数组还是可扩展的Symbol。从'../isArguments.js'导入isArgumentsconstspreadableSymbol=Symbol.isConcatSpreadablefunctionisFlattenable(value){returnArray.isArray(value)||isArguments(值)||!!(spreadableSymbol&&value&&value[spreadableSymbol])}exportdefaultisFlattenablebaseFlattenbaseFlatten可以展开数组的n级嵌套(扁平化处理),依赖isFlattenable//例子:baseFlatten([[[1,2,3],[2,2,3]],4,5,6],2)//=>[1,2,3,2,2,3,4,5,6]//isStrict==truebaseFlatten([[1,2,3],[2,2,3],4,5,6],1,null,true)//=>[1,2,3,2,2,3]importisFlattenablefrom'./isFlattenable.js的函数baseFlatten(array,depth,predicate,isStrict,result){谓词||(predicate=isFlattenable)//predicate参数是完整结果||(result=[])//返回一个新数组if(array==null){returnresult}//递归调用自己,严格模式`isStrict=true`直接退出循环for(constvalueofarray){if(depth>0&&predicate(value)){if(depth>1){//递归展平数组(易受调用堆栈限制影响)。baseFlatten(value,depth-1,predicate,isStrict,result)}else{result.push(...value)}}elseif(!isStrict){result[result.length]=value}}返回结果}导出默认值baseFlattenisLengththisLength,判断是否是一个有效的数字constMAX_SAFE_INTEGER=9007199254740991//最大数字functionisLength(value){//类型为数字且大于等于0且小于等于最大数字returntypeofvalue=='number'&&value>-1&&value%1==0&&value<=MAX_SAFE_INTEGER}exportdefaultisLengthisArrayLikeisArrayLike,判断是否为数组,依赖isLengthimportisLengthfrom'./isLength.js'functionisArrayLike(value){//value不为空,不是函数并且有length属性returnvalue!=null&&typeofvalue!='function'&&isLength(value.length)}exportdefaultisArrayLikeisArrayLikeObjectisArrayLikeObject,判断是否是数组或对象,依赖于isArrayLike和isObjectLikeimportisArrayLikefrom'./isArrayLike.js'importisObjectLikefrom'./isObjectLike.js'functionisArrayLikeObject(value){returnisObjectLike(value)&&isArrayLike(value)}exportdefaultisArrayLikeObjecteqeq,判断两个值是否相等functioneq(value,other){returnvalue===other||(值!==值&&其他!==其他)}导出默认eq||之前很好理解,判断两个值相等||后面是判断NaN的例子:constobject={'a':1}constother={'a':1}eq(object,object)//=>trueeq(object,other)//=>falseq('a','a')//=>trueeq('a',Object('a'))//=>falseq(NaN,NaN)//=>trueassocIndexOf获取“键”在键值对数组。示例:assocIndexOf([[1,2],[3,4],[5,6]],2)//=>-1assocIndexOf([[1,2],[3,4],[5,6]],3)//=>1importeqfrom'../eq.js'functionassocIndexOf(array,key){let{length}=arraywhile(length--){if(eq(array[length][0],key)){returnlength}}return-1}exportdefaultassocIndexOf