var_=require('lodash');varobj1={a:1,b:{f:{g:1}},c:[1,2,3]};varobj2=_.cloneDeep(obj1);console.log(obj1.b.f===obj2.b.f);//false(3)手写实现深拷贝函数//深拷贝的实现functiondeepCopy(object){if(!object||typeofobject!=="object")return;letnewObject=Array.isArray(object)[]:{};for(letkeyinobject){if(object.hasOwnProperty(key)){newObject[key]=typeofobject[key]==="object"deepCopy(object[key]):object[key];}}returnnewObject;}手写Object.create思路:将传入的对象作为原型
functioncreate(obj){functionF(){}F.prototype=objreturnnewF()}查找字符串中出现最多的字符和个数例:abbcccddddd->字符最多的是d,出现了5次
letstr="abcabcabcbbccccc";letnum=0;letchar='';//使其按照一定的次序排列str=str.split('').sort().join('');//"aaabbbbbcccccccc"//定义正则表达式letre=/(\w)\1+/g;str.replace(re,($0,$1)=>{if(num<$0.length){num=$0.length;char=$1;}});console.log(`字符最多的是${char},出现了${num}次`);实现add(1)(2)(3)函数柯里化概念:柯里化(Currying)是把接受多个参数的函数转变为接受一个单一参数的函数,并且返回接受余下的参数且返回结果的新函数的技术。
1)粗暴版
functionadd(a){returnfunction(b){returnfunction(c){returna+b+c;}}}console.log(add(1)(2)(3));//62)柯里化解决方案
varadd=function(m){vartemp=function(n){returnadd(m+n);}temp.toString=function(){returnm;}returntemp;};console.log(add(3)(4)(5));//12console.log(add(3)(6)(9)(25));//43对于add(3)(4)(5),其执行过程如下:
functionadd(...args){//求和returnargs.reduce((a,b)=>a+b)}functioncurrying(fn){letargs=[]returnfunctiontemp(...newArgs){if(newArgs.length){args=[...args,...newArgs]returntemp}else{letval=fn.apply(this,args)args=[]//保证再次调用时清空returnval}}}letaddCurry=currying(add)console.log(addCurry(1)(2)(3)(4,5)())//15console.log(addCurry(1)(2)(3,4,5)())//15console.log(addCurry(1)(2,3,4,5)())//15实现非负大整数相加JavaScript对数值有范围的限制,限制如下:
Number.MAX_VALUE//1.7976931348623157e+308Number.MAX_SAFE_INTEGER//9007199254740991Number.MIN_VALUE//5e-324Number.MIN_SAFE_INTEGER//-9007199254740991如果想要对一个超大的整数(>Number.MAX_SAFE_INTEGER)进行加法运算,但是又想输出一般形式,那么使用+是无法达到的,一旦数字超过Number.MAX_SAFE_INTEGER数字会被立即转换为科学计数法,并且数字精度相比以前将会有误差。
实现一个算法进行大数的相加:
functionsumBigNumber(a,b){letres='';lettemp=0;a=a.split('');b=b.split('');while(a.length||b.length||temp){temp+=~~a.pop()+~~b.pop();res=(temp%10)+res;temp=temp>9}returnres.replace(/^0+/,'');}其主要的思路如下:
Array.from(document.querySelectorAll('div'))方法二:Array.prototype.slice.call()Array.prototype.slice.call(document.querySelectorAll('div'))方法三:扩展运算符[...document.querySelectorAll('div')]方法四:利用concatArray.prototype.concat.apply([],document.querySelectorAll('div'));数组去重constarr=[1,1,'1',17,true,true,false,false,'true','a',{},{}];//=>[1,'1',17,true,false,'true','a',{},{}]方法一:利用Setconstres1=Array.from(newSet(arr));方法二:两层for循环+spliceconstunique1=arr=>{letlen=arr.length;for(leti=0;i constunique3=arr=>{constres=[];for(leti=0;i vararr=[1,2,3,4,5,6,7,8,9,10];for(vari=0;i vararr=[1,2,3,4,5,6,7,8,9,10];letlength=arr.length,randomIndex,temp;while(length){randomIndex=Math.floor(Math.random()*length--);temp=arr[length];arr[length]=arr[randomIndex];arr[randomIndex]=temp;}console.log(arr)实现prototype继承所谓的原型链继承就是让新实例的原型等于父类的实例: //父方法functionSupperFunction(flag1){this.flag1=flag1;}//子方法functionSubFunction(flag2){this.flag2=flag2;}//父实例varsuperInstance=newSupperFunction(true);//子继承父SubFunction.prototype=superInstance;//子实例varsubInstance=newSubFunction(false);//子调用自己和父的属性subInstance.flag1;//truesubInstance.flag2;//false手写Promise.all1)核心思路 2)实现代码 一般来说,Promise.all用来处理多个并发请求,也是为了页面数据构造的方便,将一个页面所用到的在不同接口的数据一起请求过来,不过,如果其中一个接口失败了,多个请求也就失败了,页面可能啥也出不来,这就看当前页面的耦合程度了 functionpromiseAll(promises){returnnewPromise(function(resolve,reject){if(!Array.isArray(promises)){thrownewTypeError(`argumentmustbeaarray`)}varresolvedCounter=0;varpromiseNum=promises.length;varresolvedResult=[];for(leti=0;i ES6方法(使用数据结构集合): constarray=[1,2,3,5,1,5,9,1,2,8];Array.from(newSet(array));//[1,2,3,5,9,8]ES5方法:使用map存储不重复的数字 constarray=[1,2,3,5,1,5,9,1,2,8];uniqueArray(array);//[1,2,3,5,9,8]functionuniqueArray(array){letmap={};letres=[];for(vari=0;i constfn=()=>{return[...newSet([...document.querySelectorAll('*')].map(el=>el.tagName))].length;}值得注意的是:DOM操作返回的是类数组,需要转换为数组之后才可以调用数组的方法。