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

美团前端双面面试题(附答案)

时间:2023-03-29 11:58:45 HTML

为什么是0.1+0.2!=0.3,请详细说明原因,因为JS使用的是IEEE754双精度版本(64位),只要使用IEEE754的语言有问题。我们都知道计算机用二进制表示小数,所以0.1用二进制表示为//(0011)表示一个循环0.1=2^-4*1.10011(0011)那么这个二进制怎么得到,我们可以计算出十进制的算术二进制不同于整数。乘法时只计算小数位,整数位作为每一位的二进制,得到的第一位为最高位。于是我们得到0.1=2^-4*1.10011(0011),那么0.2的计算基本如上所示,只需要去掉第一步的乘法,所以我们得到0.2=2^-3*1.10011(0011).回到IEEE754双精度。六十四位中,符号位占一位,整数位占十一位,其余五十二位均为小数位。因为0.1和0.2是无限循环的二进制,需要在小数点末尾判断是否进位(就像小数点四舍五入一样)。所以2^-4*1.10011...001在进位后变成2^-4*1.10011(0011*12次)010。然后将这两个二进制数相加得到2^-2*1.0011(0011*11次)0100,这个值计算为十进制0.300000000000000004先说一下原解,如下代码parseFloat((0.1+0.2).toFixed(10))常用的meta标签有哪些?Meta标签由name和content属性定义,用于描述网页的属性,如网页的作者、网页描述、关键字等,除了HTTP标准将一些名称固定为共识大家都用,开发者也可以自定义名字。常用的meta标签:(1)charset,用于描述HTML文档的编码类型:(2)keywords,页面关键词:(3)description、页面描述:(4)刷新、页面重定向和刷新:(5)viewport,适配移动端,可以控制viewport的大小和比例:其中content参数如下:widthviewport:width(value/device-width)heightviewport:height(value/device-height)initial-scale:初始缩放maximum-scale:最大缩放minimum-scale:最小缩放比例user-scalable:是否允许用户缩放(yes/no)(6)搜索引擎索引方法:其中,内容参数如下几种类型s:all:文件将被检索,可以查询页面上的链接;none:不检索文件,无法查询页面上的链接;索引:文件将被检索;follow:可以查询页面上的链接;noindex:文件不会被检索;nofollow:无法查询到页面上的链接。说说SPA单页有什么优缺点?优点:1.体验好,无刷新,减少请求数据ajax异步获取页面流程;2、前后端分离3、减轻服务器压力4、共享一套后台程序代码,适配多终端缺点:1、首屏加载太慢;2、SEO不利于搜索引擎抓取const对象的属性。const对象的属性可以修改吗?const保证的不是变量的值不能改变,而是变量指向的内存地址不能改变。对于基本类型的数据(数字、字符串、布尔值),它的值存放在变量指向的内存地址,所以相当于一个常量。但是对于引用类型的数据(主要是对象和数组),变量指向数据的内存地址,只保存一个指针。const只能保证指针是固定的。至于它指向的数据结构,是可变的吗?完全失控了。JS隐式转换,显示转换一般在转换非基本类型时,会先调用valueOf。如果valueOf无法返回基本类型值,则将调用toString字符串和数字“+”运算符。如果一个是字符串,那么既转换为字符串再进行字符串拼接“-”运算符,转换为数字,减(-a,a*1a/1)可以进行隐式强制转换[]+{}和{}+[]布尔值到数字1+true=21+false=1在第二个whileif三元表达式中转换为布尔值||(logicalor)&&(logicaland)operandsymbolsontheleftcannotbeconvertedtonumbersconvertedtoaboolean(bothtrue)canbeconvertedtoastring"Symbol(cool)"松散相等和严格相等松散相等允许强制转换,而严格相等不允许将字符串和数字转换为数字后再与其他Type和Boolean进行比较先将Boolean类型转换为数字,再继续比较对象和非对象。ToPrimitive(object)对象然后继续比较false值列表undefinednullfalse+0,-0,NaN""盒子模型的理解CSS3中的盒子模型有两种:标准盒子模型和IE盒子模型。盒子模型由四部分组成,分别是margin、border、padding和content。标准盒模型和IE盒模型的区别是在设置宽高时,对应的范围不同:标准盒模型的宽高属性的范围只包括内容,而宽高的范围IE盒模型的height属性包括border、padding和content。可以通过修改元素的box-sizing属性来改变元素的盒模型:box-sizing:content-box表示标准盒模型(默认值)box-sizing:border-box表示IE盒模型(很奇怪boxmodel)如何防止事件冒泡普通浏览器使用:event.stopPropagation()IE浏览器使用:event.cancelBubble=true;延迟加载的概念延迟加载也称为延迟加载和按需加载,是指在长网页中延迟加载图像数据。这是优化网页性能的更好方法。在一个比较长的网页或者应用中,如果图片比较多,加载完所有图片,用户只能看到可见窗口中的部分图片数据,比较浪费性能。如果使用图片的延迟加载,就可以解决上面的问题。可视区域之外的图片只有在屏幕滚动时才会加载,只有在屏幕滚动时才会加载。这使网页加载速度更快,并减少了服务器负载。懒加载适用于图片多、页面列表长(longlists)的场景。常见的HTTP请求方式GET:从服务器获取数据;POST:将实体提交到指定资源,通常会导致修改服务器资源;PUT:上传文件,更新数据;DELETE:删除服务器上的对象;HEAD:获取报告文本的头部,与GET相比,不返回报文的主体部分;OPTIONS:查询支持的请求方式,用于跨域请求;CONNECT:与代理服务器通信时需要建立隧道,使用隧道进行TCP通信;TRACE:返回显示服务器收到的请求,主要用于测试或诊断。代码输出结果Promise.reject('err!!!').then((res)=>{console.log('success',res)},(err)=>{console.log('error',err)}).catch(err=>{console.log('catch',err)})输出如下:errorerr!!!我们知道.then函数中有两个参数:第一个参数是用来处理Promise成功的函数,第二个是处理失败的函数。也就是说Promise.resolve('1')的值会进入成功的函数,Promise.reject('2')的值会进入失败的函数。在这道题中,错误直接被then的第二个参数捕获,所以不会被catch捕获,输出结果为:errorerr!!!'但是,如果像下面这样:Promise.resolve().then(functionsuccess(res){thrownewError('error!!!')},functionfail1(err){console.log('fail1',err)}).catch(functionfail2(err){console.log('fail2',err)})then的第一个参数抛出错误,那么他不会被第二个参数去激活,而是被后面的catch捕获。什么是内联元素?什么是块级元素?什么是空(void)元素?行内元素包括:abspanimginputselectstrong;块级元素包括:divulollidldtddh1h2h3h4h5h6p;空元素,即没有内容的HTML元素。空元素在开始标签中关闭,即空元素没有结束标签:常见的有:


;罕见的是:、、、。代码输出结果console.log(1)setTimeout(()=>{console.log(2)})newPromise(resolve=>{console.log(3)resolve(4)}).then(d=>console.log(d))setTimeout(()=>{console.log(5)newPromise(resolve=>{resolve(6)}).then(d=>console.log(d))})setTimeout(()=>{console.log(7)})console.log(8)输出如下:13842567代码执行过程如下:先执行脚本代码,打印出1;遇到第一个定时器,加入宏任务队列;遇到Promise,执行代码,打印3,遇到resolve,加入微任务队列;遇到第二个定时器,加入宏任务队列;遇到第三个定时器,加入宏任务队列Queue;继续执行脚本代码,打印出8,第一轮执行结束;执行微任务队列,打印出第一个Promise的解析结果:4;开始执行macrotask队列,执行第一个timer,打印出2;此时没有microtask,继续执行macrotask中的第二个timer,先打印出5,遇到Promise,先打印出6,遇到resolve,将其添加到微任务队列;执行微任务队列,打印出6;执行macrotask队列中的最后一个定时器,打印出7.这个对象的理解this是执行上下文中的一个属性,指向上次调用这个方法的对象。在实际开发中,可以通过四种调用方式来判断this的方向。首先是函数调用方式。当函数不是对象的属性,直接作为函数调用时,this指向全局对象。二是方法调用方式。如果函数作为对象的方法被调用,this指向该对象。三是构造函数调用方式。如果用new调用一个函数,在函数执行之前会创建一个新的对象,this指向新创建的对象。第四种是apply、call、bind调用方式,都可以显示指定调用函数的this点。其中apply方法接收两个参数:一个是this绑定的对象,一个是参数数组。call方法接收的参数,第一个是this绑定的对象,其余参数是传递给函数执行的参数。也就是说,在使用call()方法时,传递给函数的参数必须一一列出。bind方法接受一个对象并返回一个新函数,该函数的this绑定到传递的对象。除非使用new,否则该函数的this点不会改变。四种方法中,constructor调用方式的优先级最高,其次是apply、call、bind调用方式,其次是方法调用方式,最后是函数调用方式。什么是DOM和BOM?DOM指的是文档对象模型,是指把文档当作一个对象来对待。该对象主要定义了处理网页内容的方法和接口。BOM是指浏览器对象模型,是指把浏览器当作一个对象来对待。该对象主要定义了与浏览器交互的方法和接口。BOM的核心是窗口,窗口对象具有双重作用。它不仅是一个通过js访问浏览器窗口的接口,还是一个Global(全局)对象。这意味着网页中定义的任何对象、变量和函数都作为全局对象的属性或方法存在。window对象包含location对象、navigator对象、screen对象等子对象,DOM最基础的对象document对象也是BOM窗口对象的子对象。写代码:实现可以深度克隆基本类型的函数浅克隆:functionshallowClone(obj){letcloneObj={};for(letiinobj){cloneObj[i]=obj[i];}returncloneObj;}deepclone:考虑引用类型的基本类型RegExp、Date和非JSON安全的函数。构造函数将丢失。所有构造函数都指向Object以打破循环引用functiondeepCopy(obj){if(typeofobj==='object'){varresult=obj.constructor===Array?[]:{};for(variinobj){结果[i]=typeofobj[i]==='对象'?deepCopy(obj[i]):obj[i];}}else{varresult=obj;}returnresult;}Promise.any说明:只要promise中有一个fulfilled,就返回第一个fulfilled的Promise实例的返回值。实施Promise.any=function(promises){returnnewPromise((resolve,reject)=>{if(Array.isArray(promises)){if(promises.length===0)returnreject(newAggregateError("All承诺被拒绝了”));letcount=0;promises.forEach((item,index)=>{Promise.resolve(item).then(value=>resolve(value),reason=>{count++;if(count===promises.length){reject(newAggregateError("Allpromiseswererejected"));};});})}elsereturnreject(newTypeError("Argumentisnotiterable"));});}为什么udp不粘包?TCP协议是面向流的协议,UDP是面向消息的协议。UDP报文段就是一条消息,应用程序必须以消息为单位提取数据,不能一次提取一个字节的数据。UDP有报文边界保护,有报文头(报文源地址、端口等信息),接收端很容易区分和处理。传输协议将数据作为一个独立的消息在互联网上传输,接收端只能接收独立的消息。接收端一次只能接收到发送端发送的一个数据包。如果一次接收到的数据大小小于发送端发送的数据大小,就会丢失一部分数据。即使丢了,接收端也不会分两批接收。==运算符的强制转换规则?对于==,如果比较方的类型不同,则进行类型转换。如果比较x和y是否相同,会进行如下判断过程:首先判断两个类型是否相同,如果相同则比较两者的大小;如果类型不相同,则进行类型转换;首先判断是否在比较null和undefined,如果是则返回true判断这两个类型是否是string和number,如果是则将string转为number1=='1'↓1==1判断其中一个是否为boolean,如果是,则将boolean转化为number,然后判断'1'==true↓'1'==1↓1==1判断其中一个是否为anobject,另一个是string,number或者symbol,如果是,则转换object然后判断为原始类型'1'=={name:'js'}↓'1'=='[objectObject]'使用clear属性清除浮动的原理?使用clear属性清除浮动。语法如下:clear:none|left|right|both如果看字面意思,clear:left的意思是“清除左浮动”,clear:right的意思是“清除右浮动”。其实这个解释是有问题的,因为float还在,没有被清除。clear属性官方解释:“元素框的边缘不能与上一个浮动元素相邻”。给元素设置clear属性是为了避免浮动元素对元素的影响,并不是清除浮动元素。还需要注意的是,clear属性是指元素框的边缘不能与前面的浮动元素相邻。注意这里的“前”三个字,即clear属性对“后”的浮动元素无动于衷。考虑到float属性不是左就是右,不可能同时存在。同时,由于clear属性对“后面”的浮动元素无动于衷,所以当clear:left有效时,clear:right必然无效。就是这个时候clear:left相当于设置clear:both;类似地,clear:right等同于设置clear:both如果它有效。可见clear:left和clear:right这两个声明是没有任何使用价值的,至少在CSS的世界里是这样,所以直接使用clear:both。一般使用伪元素清除浮点数:.clear::after{content:'';显示:块;clear:both;}clear属性只对块级元素有效,而::after等伪元素默认是内部的。这就是为什么在使用伪元素清除浮动效果时需要设置display属性的值。