当前位置: 首页 > 科技观察

32个手撕JS,彻底摆脱初级前端(高频面试)-篇

时间:2023-03-12 04:39:24 科技观察

源码全部符合规范,可以跑遍MDN例子。剩下的大部分会涉及到一些关于JS的应用题和面试流程01.数组扁平化数组扁平化是指将一个多维数组变成一维数组constarr=[1,[2,[3,[4,5]]],6];//=>[1,2,3,4,5,6]复制代码方法一:使用flat()constres1=arr.flat(Infinity);复制代码方法二:使用正则constres2=JSON.stringify(arr).replace(/\[|\]/g,'').split(',');复制代码但数据类型会变成字符串/\[|\]/g,'')+']');复制代码方法四:使用reduceconstflatten=arr=>{returnarr.reduce((pre,cur)=>{returnpre.concat(Array.isArray(cur)?flatten(cur):cur);},[])}constres4=flatten(arr);复制代码方法五:函数递归constres5=[];constfn=arr=>{for(leti=0;i[1,'1',17,true,false,'true','a',{},{}]复制代码方法一:使用Setconstres1=Array.from(newSet(arr));复制代码方法二:两层for循环+spliceconstunique1=arr=>{letlen=arr.length;for(leti=0;i{constres=[];for(leti=0;i{constres=[];for(leti=0;i{returnarr.filter((item,index)=>{returnarr.indexOf(item)===index;});}复制代码方法六:使用Mapconstunique5=arr=>{constmap=newMap();constres=[];for(leti=0;i>>0保证len是一个数和一个正整数constlen=O.length>>>0;for(leti=0;i>>0:解释>>>005.Array.prototype.map()Array.prototype.map=function(callback,thisArg){if(this==undefined){thrownewTypeError('thisisnullornotdefined');}if(typeofcallback)的作用!=='福nction'){thrownewTypeError(callback+'isnotafunction');}constres=[];//类似constO=Object(this);constlen=O.length>>>0;for(leti=0;i>>0;letk=0;while(k>>0;letaccumulator=initialValue;letk=0;//如果第二个参数未定义//第一个数组的有效值作为累加器的初值数组初始值,然后TypeErrorif(k>=len){thrownewTypeError('Reduceofemptyarraywithnoinitialvalue');}accumulator=O[k++];}while(k{lettimeout=null;returnfunction(){clearTimeout(timeout)timeout=setTimeout(()=>{fn.apply(this,arguments);},time);}};防抖常用于用户搜索输入,节省请求资源。当窗口触发resize事件时,防抖只会触发一次。12、throttle(节流阀)高频时间触发,但是n秒只会执行一次,所以throttling会稀释函数的执行频率。constthrottle=(fn,time)=>{letflag=true;returnfunction(){if(!flag)return;flag=false;setTimeout(()=>{fn.apply(this,arguments);flag=true;},time);}}复制代码节流通常应用于鼠标点击以触发和监视滚动事件。13.柯里化函数是指把一个接受多个参数的函数变成一个固定的接受一个参数返回函数的形式,这样方便再次调用,比如f(1)(2)经典面试题:implement添加(1)(2)(3)(4)=10;,添加(1)(1,2,3)(2)=9;functionadd(){const_args=[...arguments];functionfn(){_args.推(...参数);returnfn;}fn.toString=function(){return_args.reduce((sum,cur)=>sum+cur);}returnfn;}复制代码14.模拟new操作分3步:创建一个对象,ctor.prototype为原型。执行构造函数并将其绑定到新创建的对象。判断构造函数执行返回的结果是否为引用数据类型,如果是则返回构造函数执行的结果,否则返回创建的对象。functionnewOperator(ctor,...args){if(typeofctor!=='function'){thrownewTypeError('TypeError');}constobj=Object.create(ctor.prototype);constres=ctor.apply(obj,args);constisObject=typeofres==='object'&&res!==null;constisFunction=typeofres==='function';returnisObject||isFunction?res:obj;}复制代码15.instanceofinstanceof操作符用于检测原型constructor属性是否出现在实例对象的原型链上。constmyInstanceof=(left,right)=>{//基本数据类型返回falseif(typeofleft!=='object'||left===null)returnfalse;letproto=Object.getPrototypeOf(left);while(true){if(proto===null)返回false;如果(proto===right.prototype)返回真;proto=Object.getPrototypeOf(proto);}}复制代码16.原型继承这里只写寄生组合继承,还有几种进化继承,但都有一些缺陷functionParent(){this.name='parent';}functionChild(){Parent.call(this);this.type='children';}Child.prototype=对象。创建(Parent.prototype);Child.prototype.constructor=Child;复制代码