代码输出结果setTimeout(function(){console.log(1);},100);newPromise(function(resolve){console.log(2);resolve();console.log(3);}).then(function(){console.log(4);newPromise((resove,reject)=>{console.log(5);setTimeout(()=>{console.log(6);},10);})});console.log(7);console.log(8);输出结果为:23784561代码执行过程如下:首先遇到定时器,将其添加到宏任务队列中;遇到Promise,先执行里面的同步代码,打印出2,遇到resolve,加入microtask队列,执行后面的同步代码,打印出3;继续执行脚本中的代码,打印出7和8,至此第一轮代码执行完毕;执行microtask队列中的代码,先打印出4,如果遇到Promise,执行里面的同步代码,打印出5,遇到timer,就加入到macrotask队列中,此时有两个宏任务队列中的计时器;执行宏任务队列中的代码,这里需要注意第一个定时器的时间是100ms,第二个定时器的时间是10ms,所以先执行第二个定时器,打印出6;此时microtask队列为空,继续执行macrotask队列,打印出1。完成本题后,需要特别注意各个timer的时间,并不是所有的timer都为0。代码输出结果函数a(){console.log(this);}a.call(null);打印结果:window对象根据ECMAScript262规范:如果作为第一个参数传入的对象调用者为null或undefined,则call方法会将全局对象(浏览器中的window对象)作为this的值。所以不管传入null还是undefined,它的this都是全局对象窗口。所以,在浏览器上答案是输出窗口对象。请注意,在严格模式下,null为null,undefined为未定义:'usestrict';functiona(){console.log(this);}a.call(null);//nulla.call(undefined);//undefined前端高级面试题详解手写题:数组展平函数flatten(arr){letresult=[];for(leti=0;iconsole.log(a))}(2)使用Array.from方法将类数组转换为数组:?functionfoo(){constarrArgs=Array.from(arguments)arrArgs.forEach(a=>console.log(a))}(3)使用展开运算符将类数组转为数组functionfoo(){constarrArgs=[...arguments]arrArgs.forEach(a=>console.log(a))}transition和animation的区别是transition是一个transition属性,强调transition,它的实现需要触发一个事件(比如鼠标移动,focus,click等)来执行动画。类似于Flash的补间动画,设置开始关键帧和结束关键帧。animation是一个动画属性,它的实现不需要触发事件,设置时间后就可以执行,可以循环播放一个动画。它也类似于flash的补间动画,但是可以设置多个关键帧(用@keyframe定义)来完成动画。大数相加题目描述:实现一个add方法完成两个大数相加leta="9007199254740991";letb="1234567899999999999";functionadd(a,b){//...}实现代码如下:functionadd(a,b){//取两个数的最大长度letmaxLength=Math.max(a.length,b.length);//用0填充长度a=a.padStart(maxLength,0);//"0009007199254740991"b=b.padStart(maxLength,0);//"1234567899999999999"//定义需要使用的变量在加法过程中让t=0;让f=0;//“进位”letsum="";for(leti=maxLength-1;i>=0;i--){t=parseInt(a[i])+parseInt(b[i])+f;f=Math.floor(t/10);总和=t%10+总和;}if(f!==0){sum=''+f+sum;}returnsum;}寄生组合继承题目描述:实现一个自己觉得不错的js继承方法的实现代码如下:functionParent(name){this.name=name;this.say=()=>{console.log(111);};}Parent.prototype.play=()=>{控制台。日志(222);};函数儿童(名称){Parent.call(this);this.name=name;}Children.prototype=Object.create(Parent.prototype);Childrenn.prototype.constructor=Children;//letchild=newChildren("111");////console.log(child.name);////child.say();////孩子。玩();数组有哪些原生方法?数组和字符串的转换方法:toString()、toLocalString()、join()其中,join()方法在转换为字符串时可以指定定界符数组尾操作方法pop()和push(),push方法可以传入多个参数。用于数组头操作的方法shift()和unshift()以及用于重新排序的方法reverse()和sort()。sort()方法可以传入一个比较函数,传入前后两个值。如果返回值为正数,则交换两个参数的位置。数组连接的concat()方法返回连接后的数组而不影响原始数组。数组截取方法slice()用于在不影响原数组的情况下截取数组的一部分返回。数组插入方法splice()、影响原数组查找特定项索引的方法、indexOf()和lastIndexOf()迭代方法every()、some()、filter()、map()和forEach()方法数组合并方法reduce()和reduceRight()方法说说前端登录流程?首次登录时,前端调整登录界面,发送用户名和密码,后端接收请求,验证用户名和密码,并向前端返回一个token和用户信息的价值。前端拿到token,将token存入Vuex中,然后从Vuex中将token的值存入浏览器的Cookies中。将用户信息保存在Vuex中,然后存储到LocalStroage中,然后跳转到下一个页面。根据后台接口的要求,对于不登录就无法访问的页面,需要在页面中每次有cookie时在前端进行判断。token,没有token就跳转到登录页面,有token就跳转到对应页面。我们应该在每次发送post/get请求时添加令牌。常用的方法是在项目utils/service.js中添加一个全局拦截器。将token值放入请求头,后端判断请求头中是否有token。如果有token,则获取token并验证token是否过期。这里,过期会返回一个无效的token,然后会跳回到登录页面重新登录以及如何清除本地用户信息如何防止事件冒泡常见浏览器使用:event.stopPropagation()IE浏览器使用:event.cancelBubble=true;使用PWA?serviceWorker的使用原理是什么?Progressivewebapplication(PWA)是Google在2015年底提出的一个概念。基本上是一个web应用程序,但外观和感觉类似于原生应用程序。支持PWA的网站可以提供离线工作、推送通知和设备硬件访问等功能。ServiceWorkers是浏览器独立于网页在后台运行的脚本,为不需要网页或用户交互的功能打开了大门。它们现在包括推送通知和后台同步等功能。将来,ServiceWorkers将支持其他功能,例如定期同步或地理围栏。本教程中讨论的核心功能是拦截和处理网络请求,包括以编程方式管理缓存中的响应。防抖功能触发高频事件,N秒后只会执行一次。如果在N秒内再次触发该事件,则重新开始计时。简易版:函数支持使用this和event对象;函数去抖动(func,等待){var超时;返回函数(){varcontext=this;var参数=参数;clearTimeout(timeout)timeout=setTimeout(function(){func.apply(context,args)},wait);}}use:varnode=document.getElementById('layout')functiongetUserAction(e){console.log(this,e)//分别打印:nodethisnode和MouseEventnode.innerHTML=count++;};node.onmousemove=debounce(getUserAction,1000)最终版:除了支持this和event外,还支持以下功能:支持立即执行;函数可能有返回值;支持注销功能;functiondebounce(func,wait,immediate){vartimeout,result;vardebounced=function(){varcontext=this;var参数=参数;如果(超时)clearTimeout(超时);if(immediate){//如果已经执行varcallNow=!timeout;timeout=setTimeout(function(){timeout=null;},wait)if(callNow)结果=func.apply(context,args)}else{timeout=setTimeout(function(){func.apply(context,args)},wait);}返回结果;};debounced.cancel=function(){clearTimeout(超时);超时=空;};returndebounced;}use:varsetUseAction=debounce(getUserAction,10000,true);//使用防抖node.onmousemove=setUseAction//取消防抖setUseAction.cancel()position属性有哪些,有什么区别?Relative生成??相对定位的元素,相对于它们的原始位置定位。元素的位置由left、top、right和bottom属性指定。fixed生成绝对定位的元素,指定元素相对于屏幕视口(viewport)的位置来指定元素的位置。当屏幕滚动时,元素的位置不会改变。例如,返回顶部的按钮通常采用这种方式定位。static默认值,无定位,元素出现在正常文档流中,top,bottom,left,right或z-index声明被忽略,块级元素从上到下垂直排列,行级元素从上到下排列左到右。inherit规定从父元素继承position属性值的前三个元素的定位方式如下:relative:元素的定位总是相对于元素本身的位置,与元素无关其他元素,不会影响其他元素。fixed:元素的定位是相对于window(或iframe)边界的,与其他元素无关。但它具有破坏性,会导致其他元素位置发生变化。absolute:元素的定位比前两种复杂很多。如果top和left设置为absolute,浏览器将使用什么来确定其垂直和水平偏移量?答案是浏览器会递归搜索该元素的所有父元素。如果它找到一个设置了position:relative/absolute/fixed的元素,它将基于该元素进行定位。如果没有找到,将基于浏览器边界定位。如下两图所示:告诉我如何取出数组中最多的一项?//我这里只是一个例子constd={};letary=['赵','钱','孙','孙','李','周','李','周','周','李'];ary.forEach(k=>!d[k]?d[k]=1:d[k]++);constresult=Object.keys(d).sort((a,b)=>d[b]-d[a]).filter((k,i,l)=>d[k]===d[l[0]]);console.log(result)切片思维解决大数据渲染问题题目描述:结构简单的百万级大数据渲染时如何使用切片思维优化渲染实现代码如下:letul=document.getElementById("container");//插入十万条数据lettotal=100000;//一次插入20条记录letonce=20;//总页数letpage=total/once;//Indexofeachrecordletindex=0;//循环加载数据functionloop(curTotal,curIndex){if(curTotal<=0){returnfalse;}//每页多少条letpageCount=Math.min(curTotal,once);window.requestAnimationFrame(function(){for(leti=0;i