当前位置: 首页 > Web前端 > HTML5

daily-question-02(前端每日题02)

时间:2023-04-04 23:13:45 HTML5

这里记录了一个印象深刻的前端问题,每天都会遇到,还有一个生活中随处可见的小问题。强迫自己养成积累的习惯,鞭策自己不断前行,共同学习。Github地址2019/04/15-2019/04/211。写一个随机函数?遍历数组元素,然后将当前元素与未来随机位置的元素交换。functionshuffle(a){for(leti=a.length;i;i--){letj=Math.floor(Math.random()*i);//es6语法[a[i-1],a[j]]=[a[j],a[i-1]];}返回一个;}2。什么是惰性函数?惰性函数是返回重写函数的函数。例如:varfoo=function(){vart=newDate();foo=function(){返回t;};返回foo();};富();3.静态作用域与动态作用域?静态作用域——函数的作用域基于创建函数的位置。动态作用域——函数的作用域基于函数的使用位置。varvalue=1;functionfoo(){console.log(value);}functionbar(){varvalue=2;foo();}bar();//输出1.JavaScript使用词法作用域,也称为静态作用域。同样,这段带有动态作用域的代码应该输出24。手写一个函数call()函数?Function.prototype.call2=function(context,...args){//因为传入的context可能为nullcontext=context||窗户;//Function.prototypethis是当前运行的函数//让fn的上下文为contextcontext.fn=this;constresult=context.fn(...args);删除context.fn;返回结果;};5.vue组件中name属性的作用?当使用Vue.component()全局注册组件时,全局ID将自动用作组件的名称。指定名称选项的另一个好处是易于调试。具有名称的组件具有更友好的警告消息。还有,在使用vue-devtools的时候,未命名的组件会显示为,非常没有意义。通过提供name选项可以获得更多语义信息的组件树。6、Hash路由和History路由有什么区别?哈希路由哈希路由的一个明显标志就是#,我们主要通过监听url中的哈希变化来进行路由跳转。(window.addEventListener('hashchange',this.refresh,false);)hash的好处是兼容性比较好,在老版本的IE中运行。问题是url里面一直有#,不够漂亮,hash路由更像是ItisHack而不是standard。我相信随着更加标准化的HistoryAPI的发展,哈希路由的市场会逐渐被蚕食。historyrouting历史路由使用HistoryAPI实现,具体为:window.history.back();//返回window.history.forward();//转发window.history.go(-3);//返回三页面history.pushState用于在浏览历史中添加历史记录。history.replaceState方法的参数与pushState方法完全相同。不同的是,它修改的是浏览历史中的当前记录,而不是增加一条记录,同样不会触发跳转。7、Vue响应式原理中Object.defineProperty的缺陷是什么?为什么在Vue3.0中采用了Proxy而放弃了Object.defineProperty?Object.defineProperty无法监听数组下标的变化,导致通过数组下标添加元素,无法实时响应;Object.defineProperty只能劫持对象的属性,所以需要遍历每个对象和每个属性。如果,属性值是一个对象,需要深度遍历。代理可以劫持整个对象并返回一个新对象。Proxy不仅可以代理对象,还可以代理数组。也可以代理动态增加的属性。2019/04/08-2019/04/144。写个“终端类型”判断函数?函数类型(obj){vartoString=Object.prototype.toString;vartoType={};vartypeArr=["Undefined","Null","Boolean","Number","String","Object","Array","Function","Date","RegExp","Error","Arguments"];//这里object对象的值toString()用于判断'[objectArray]'的值等typeArr.map(function(item,index){toType["[object"+item+"]"]=item.toLowerCase();});返回类型obj!==“对象”?obj类型:toType[toString.call(obj)];}2。写一个函数判断各种类型的不同变量是否相等,即“最终相等”函数?constequals=(a,b)=>{如果(a===b)返回真;//时间判断if(ainstanceofDate&&binstanceofDate)returna.getTime()===b.getTime();//非对象类型判断if(!a||!b||(typeofa!=="object"&&typeofb!=="object"))returna===b;if(a.prototype!==b.prototype)返回false;if(Array.isArray(a)&&Array.isArray(b))a.sort(),b.sort();让keys=Object.keys(a);如果(keys.length!==Object.keys(b).length)返回false;返回keys.every(k=>equals(a[k],b[k]));};3.mouseover和mouseenter有什么区别?mouseover:当鼠标移入元素或其子元素时,会触发该事件,所以存在重复触发,冒泡过程对应的移除事件为mouseoutmouseenter:当鼠标移除元素本身(不包括元素的子元素),会触发该事件,即不会冒泡,对应的移除事件为mouseleave4。一句话形容闭包?闭包是一个函数,可以读取其他函数的内部变量,或者在外部调用子函数,子函数所在的父函数作用域不会被释放。一个闭包栗子:functionf1(){  n=999;  functionf2(){    console.log(n);  }  返回f2;}varresult=f1();  //返回f2函数result();  //999,读取内部变量5.js的new运算符有什么作用?new操作符创建一个新的空对象,对象原型指向构造函数的原型,该对象在构造函数执行后返回。6.实现深拷贝?//所谓深克隆是指当对象的某个属性值为对象或数组时,需要获取拷贝而不是直接获取引用值函数deepClone1(origin,target){//origin是克隆出来的对象,target是我们得到的副本vartarget=target||{};//Definetargetfor(varkeyinorigin){//遍历原始对象if(origin.hasOwnProperty(key)){if(Array.isArray(origin[key])){//如果是数组target[键]=[];deepClone1(原点[键],目标[键]);//递归}elseif(typeoforigin[key]==="object"&&origin[key]!==null){target[key]={};deepClone1(原点[键],目标[键]);//递归}else{target[key]=origin[key];}}}returntarget;}//第二个函数functiondeepClone2(data){if(!data||!(datainstanceofObject)||typeofdata==="function"){returndata;}varconstructor=data.constructor;varresult=newconstructor();for(varkeyindata){if(data.hasOwnProperty(key)){result[key]=deepClone2(data[key]);}}返回结果;}//第三个fuctionfunctiondeepClone3(origin,target){vartarget=target||{},toStr=Object.prototype.toString;for(varpropinorigin){if(origin.hasOwnProperty(prop)){//不能把链上的原型复制在一起//判断是元素类型还是引用类型if(typeoforigin[prop]=="object"&&typeoforigin[prop]!=="null"){target[prop]=toStr.call(prop)=="[objectArray]"?[]:{};arguments.callee(原点[prop],target[prop]);//递归调用}else{target[prop]=origin[prop];//origin类型直接复制}}}returntarget;}//第四个函数functiondeepClone4(obj){//判断是否为简单数据类型,if(typeofobj=="object"){//复杂数据类型varresult=obj.constructor==数组?[]:{};for(letiinobj){result[i]=typeofobj[i]=="object"&&obj[i]!==null?deepClone4(obj[i]):obj[i];}}else{//简单数据类型direct==assignmentvarresult=obj;}返回结果;防抖所谓防抖是指功能只能在事件触发后n秒内执行一次,如果n秒内再次触发事件,函数执行时间将重新计算(防误触)//延迟执行functiondebounce(func,wait){vartimeout;返回函数(){varcontext=this;var参数=参数;控制台日志(参数);控制台日志(功能);如果(超时)clearTimeout(超时);timeout=setTimeout(function(){func.apply(context,args);},wait);};}//立即执行函数debounce(func,wait){vartimeout;返回函数(){varcontext=this;var参数=参数;如果(超时)clearTimeout(超时);varcallNow=!timeout;timeout=setTimeout(function(){timeout=null;},等待);如果(callNow)func.apply(context,args);};}节流所谓节流是指连续触发事件,但n秒只执行一次函数。(限制流量)//时间间隔functionthrottle(func,wait){varprevious=0;返回函数(){varnow=Date.now();变量上下文=这个;var参数=参数;if(now-previous>wait){func.apply(context,args);以前=现在;}};}//定时器functionthrottle(func,wait){vartimeout;返回函数(){varcontext=this;var参数=参数;如果(!timeout){timeout=setTimeout(function(){timeout=null;func.apply(context,args);},等待);}};}