高楼拔地而起,地基牢固,方能立于不败之地。今天给大家带来的是10个常用的JavaScript手写函数,重要的地方都加了注释。有些是从别人那里借来的,有些是自己写的。如果有不准确的地方,请指正。1.防抖功能debounce(fn,delay){lettimerreturnfunction(...args){if(timer){clearTimeout(timer)}timer=setTimeout(()=>{fn.apply(this,args)},delay)}}//测试函数task(){console.log('runtask')}constdebounceTask=debounce(task,1000)window.addEventListener('scroll',debounceTask)2.节流函数throttle(fn,delay){letlast=0//最后一次触发时间return(...args)=>{constnow=Date.now()if(now-last>delay){last=nowfn.apply(this,args)}}}//测试functiontask(){console.log('runtask')}constthrottleTask=throttle(task,1000)window.addEventListener('scroll',throttleTask)3,深拷贝函数deepClone(obj,cache=newWeakMap()){if(typeofobj!=='object')returnobj//普通类型,直接返回if(obj===null)returnobjif(cache.get(obj))returncache.get(obj)//防止循环引用,程序进入死循环if(objinstanceofDate)returnnewDate(obj)if(objinstanceofRegExp)returnnewRegExp(obj)//找到原型上的构造函数,原型上的构造函数指向constructorofthecurrentobjectletcloneObj=newobj.constructor()cache.set(obj,cloneObj)//缓存复制对象,用于处理循环引用for(letkeyinobj){if(obj.hasOwnProperty(key)){cloneObj[key]=deepClone(obj[key],cache)//递归复制}}returncloneObj}//测试constobj={name:'Jack',address:{x:100,y:200}}obj.a=obj//循环引用constnewObj=deepClone(obj)console.log(newObj.address===obj.address)//false4,实现PromiseclassMyPromise{constructor(executor){//executor执行器this.status='pending'//等待状态this.value=null//成功或失败参数this.fulfilledCallbacks=[]//成功函数队列this.rejectedCallbacks=[]//失败函数队列constthat=thisfunctionresolve(value){//成功方法if(that.status==='pending'){that.status='resolved'that.value=valuethat.fulfilledCallbacks.forEach(myFn=>myFn(that.value))//执行回调方法}}functionreject(value){//failedmethodif(that.status==='pending'){that.status='rejected'that.value=valuethat.rejectedCallbacks.forEach(myFn=>myFn(that.value))//执行回调方法}}try{executor(resolve,reject)}catch(err){reject(err)}}then(onFulfilled,onRejected){if(this.status==='pending'){//waitingstatus,Addacallbackfunctiontothesuccessfulfunctionqueuethis.fulfilledCallbacks.push(()=>{onFulfilled(this.value)})//等待状态,添加回调函数到失败函数队列this.rejectedCallbacks。脓h(()=>{onRejected(this.value)})}if(this.status==='resolved'){//支持同步调用console.log('this',this)onFulfilled(this.value)}if(this.status==='rejected'){//支持同步调用onRejected(this.value)}}}//测试函数fn(){returnnewMyPromise((resolve,reject)=>{setTimeout(()=>{if(Math.random()>0.6){resolve(1)}else{reject(2)}},1000)})}fn().then(res=>{console.log('res',res)//res1},err=>{console.log('err',err)//err2})5.异步控制并发函数limitRequest(urls=[],limit=3){returnnewPromise((resolve,reject)=>{constlen=urls.lengthletcount=0//当前任务数conststart=async()=>{consturl=urls.shift()//从数组中获取第一个任务if(url){try{awaitaxios.post(url)if(count==len-1){//上一个任务成功resolve()}else{count++//成功,开始下一个任务start()}}catch(e){if(count==len-1){//上一个任务失败resolve()}else{count++//失败,开始下一个任务start()}}}}//开始限制任务while(limit>0){start()限制-=1}})}//测试limitRequest(['http://xxa','http://xxb','http://xxc','http://xxd','http://xxe'])6、ES5继承(寄生组合继承)functionParent(name){this.name=name}Parent.prototype.eat=function(){console.log(this.name+'iseating')}functionChild(name,age){Parent.call(this,name)this.age=age}Child.prototype=Object.create(Parent.prototype)Child.prototype.contructor=ChildChild.prototype.study=function(){console.log(this.name+'isstudying')}//测试letchild=newChild('xiaoming',16)console.log(child.name)//xiaomingchild.eat()//xiaomingisingchild.study()//xiaomingistudying7、数组排序sortsorting//对数字进行排序,简写为constarr=[3,2,4,1,5]arr。sort((a,b)=>a-b)console.log(arr)//[1,2,3,4,5]//对字母进行排序,简写constarr=['b','c','a','e','d']arr.sort()console.log(arr)//['a','b','c','d','e']冒泡排序函数bubbleSort(arr){letlen=arr.lengthfor(leti=0;i
