美文网首页
2020前端面试

2020前端面试

作者: Poppy11 | 来源:发表于2020-09-24 22:13 被阅读0次

    https://github.com/haizlin/fe-interview

    2、http缓存

    • 强缓存
      强缓存就是给资源设置个过期时间,客户端每次请求资源时都会看是否过期;只有在过期才会去询问服务器。
      不会向服务器发送请求,直接从缓存中读取资源
    • 协商缓存
      请求资源时,服务端和最新资源做对比。
      如果资源没更改,返回304,浏览器读取本地缓存。
      如果资源有更改,返回200,返回最新的资源。
      协商缓存和强缓存使用场景:服务器上的资源会更新,这个时候如果我们还访问本地缓存,那么对用户来说,那就相当于资源没有更新,用户看到的还是旧的资源;所以我们希望服务器上的资源更新了浏览器就请求新的资源,没有更新就使用本地的缓存,以最大程度的减少因网络请求而产生的资源浪费。所以一般会使用协商缓存
    • 本地存储
      本地存储主要有以下几种,localStorage、sessionStorage、cookie、websql、indexDB.

    localStorage
    在前端设置,可以减少数据请求,长期存储。
    sessionStorage
    在前端设置,只存在当前会话中即重新打开浏览器则数据消失
    cookie
    在后端设置,保存在客户端本地文件,通过set-cookie设置且Cookie的内容自动在请求的时候被传递到服务器

    3、nginx负载均衡

    使用upstream设置不同的服务器,以便每次访问的时候,都会访问到不同的服务器


    image.png

    5、key使用index会有什么问题

    key是这条数据唯一的标识,用来追踪列表中哪条元素进行变动了。如果数组某项数据删除,以前的数据和重新渲染后的数据随着 key 值的变化从而没法建立关联关系. 这就失去了 key 值存在的意义,可能就会导致数据错乱。一般都会使用每条数据的id,因为id是唯一的

    6、css优先级

    内联样式>ID选择器>类选择器(Class)

    8、绝对定位和相对定位的区别

    绝对定位:是相对于元素最近的已定位的祖先元素,如果元素没有已定位的祖先元素,那么它的位置则是相对于body
    相对定位:相对于元素在文档中的初始位置

    9、let、const、var的区别

    const一般用于声明常量,var和let一般用于声明变量
    const和let不能重复定义属性名,而var可以,并且var存在变量提升的现象
    var可以跨快访问

    10、get和post的区别

    get返回时,不会重新请求,而post返回时,会重新提交表单
    get没有post安全,因为get请求参数直接暴露在url上
    get参数通过url传递,post放在body中
    get请求参数长度有限制,post没有
    get请求参数会被保存在浏览器历史中,而post不会

    11、常用状态码

    200 - 成功
    301 - 重定向
    304 - 一般用于协商缓存,向后台发请求读取资源,如果本地有缓存,则返回304读取本地缓存
    400 - 前台数据格式有错误
    401 - 权限不足
    403 - 服务器拒绝请求
    500 - 服务器内部错误
    503 - 服务器维护

    12、react调用setState后发生了什么

    react会触发调和过程,react会以相对高效的方式根据新的状态构建react元素树并且重新渲染界面,react会自动计算新数树与旧树的差异,然后根据差异来渲染。

    14、react为什么虚拟 dom 会提高性能?

    虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。传统diff算法复杂度达到 O(n^3) ,n是树的节点数,而虚拟dom中的Diff算法复杂度只需要O(n)复杂度

    15、了解redux吗?

    redux是公共管理状态的,主要有三个核心方法,action,reducer,store,工作流程就是view调用dispatch触发action,action可以写异步操作,然后分发dispatch,reducer会根据action分发的dispatch中的type和state来更新状态。当我们在组件中使用则需要使用connect将组件与store连接起来。

    16、JS事件循环

    首先JS是单线程的,一般的代码都会按顺序执行,如果遇到异步代码,会将异步代码放到另一个线程,这个线程我们叫工作线程,主线程继续执行剩余的代码,当工作线程异步代码执行完成过后,比如setTimeout时间到了或者axios得到了数据,该线程就会将回调函数放到消息队列里面去,当主线程代码执行完过后,会检查任务队列是否有任务要执行,如果有,则会执行,如果没有,则会一直循环等待任务到来。

    17、什么是闭包和内存泄漏

    闭包通俗来讲,就是a函数里面还有b函数,而b函数可以访问a函数里面的变量。
    因为闭包会携带它的函数的作用域,这样会导致多余的内存被占用,这就是内存泄漏
    在推出函数之前,将变量赋值为null,就可解决内存泄漏

    18、async和await的原理和使用

    在异步代码的函数上加上async,在异步代码前加上await,这样使用的话,我们即使调用的异步代码,也会变成类似于同步,只有让这个异步代码执行完过后,才会执行下面的代码,好处就是promise一般会通过then方法来获取异步数据,如果过多的话,就会造成回调地狱,代码可读性差,使用async/await可以使代码很简洁。

    19、MVVM是什么?

    MVVM即Model-View-ViewModel的简写。模型(Model)指的是后端传递的数据。视图(View)指的是所看到的页面。视图模型(ViewModel)是mvvm模式的核心,它是连接view和model的桥梁。例如react的state和vue的data里面,然后页面数据是从这个state或data里面取到的

    20、css和less区别

    less是css预处理语言,扩展了css。

    • less可以声明变量,@color: #4D926F;
    • less可以混合,即b样式可以直接调用a样式

    21、form表单提交和ajax提交表单区别

    • ajax是异步的,网页不需要刷新,form表单提交则需要刷新
    • ajax提交是在后台新建请求,form表单则是趋势放弃本页面,再申请

    22、Promise是什么?

    promise是一个对象,内部有三个状态,resolved,rejected,pending。当我们new一个promise对象的时候,会传入一个回调函数,这回调函数有resolve和reject两个方法。想改变状态只能调用resolve()或者reject()这两个方法,并且resolve可以将异步数据存储在内部data里面,然后他们通过.then方法来获取数据,then方法可以接受两个参数,一个成功的回调,一个失败的回调。但是我们获取数据一般是通过async/await来获取数据。这样可以避免回调地狱。

    23、高阶函数是什么?

    高阶函数就是指函数作为可以作为另外一个函数的参数

    24、组件化开发有什么好处?

    • 可组合:便于将复杂的UI拆分成多个简单的UI组件
    • 可复用:每个组件都具有独立功能,可使用在多个场景
    • 便于维护:每个组件都有自己的功能,便于开发者维护

    25、什么是跨域?

    当一个url的协议、域名、端口三者之间任意一个与当前url不同即为跨域,跨域则是因为受到浏览器同源策略的限制,同源就是指两个页面具有相同的协议、域名、端口号。

    26、怎么解决跨域?

    • 1、nginx反向代理
    • 2、jsonp请求,但是只能处理get请求
    • 3、CORS跨域
      cors全称是跨域资源共享,cors需要浏览器和服务器同时支持,浏览器会将请求分为两大类,一类是简单请求,一类是复杂请求.
    • 简单请求一般就是get,post,并且头部信息也不能带多余的参数,当浏览器发现是简单请求时,请求头会多一个字段origin,origin会指出当前请求属于哪个域,服务器会根据这个值决定是否允许跨域。
    • 特殊请求,例如put,delete等,则会在发送请求之前先发送一个预检测请求,服务器收到预检测请求,如果允许跨域,客户端则能成功发送请求

    27、react框架的优点

    1、react速度快,因为含有虚拟dom
    2、组件化,便于维护
    3、单向数据流,便于阅读代码
    4、纯粹的javaScript语法,没有任何专有的react语法

    28、vue框架和react框架的区别

    • vue使用html模板进行渲染,只是在html上多了一些特有的属性,例如v-for,v-if等,而react则是使用jsx语法,jsx语法则是可以再javaScript中写html

    29、什么是回调函数?

    回调函数则是函数作为参数传入另外一个函数,这个作为参数的函数会在某个时机被调用,这就是回调函数

    30、xss跨站脚本如何进行?防御手段?

    如何进行:xss是指恶意攻击者利用网站没有对用户提交的数据进行过滤处理,进而添加一些恶意代码,嵌入到Web页面,从而利用用户的身份进行某种动作
    防御手段:不信任客户端提交的任何数据,只要是客户端提交的就应该先进行对应的过滤处理。

    31、CSRF跨站请求伪造如何进行?防御手段?

    如何进行:当用户在某网页登录后,在没有关闭网页的情况下,收到恶意链接,点击链接,则会利用浏览器的cookie把密码改掉。
    防御手段:后端使用jwt技术验证token,使用axios请求

    32、web上传漏洞如何进行?防御手段?

    如何进行:用户上传了一个可执行的脚本文件,并通过脚本文件获得了执行服务器端命令的能力
    防御手段:1、前后端都对文件后缀名进行限制
    2、吧文件上传目录的权限设置为只读

    33、什么是盒子模型?

    盒子模型从外到内由margin、border、padding、content组成

    34、简要说一下css的元素分类

    块级元素:div,p,h1,form,ul,li;
    行内元素 : span,a,label,input,img,strong,em;

    35、axios有什么好处?

    • 支持promise语法
    • 拦截请求头和响应
    • 自动转换json数据
    • 客户端支持防止csrf

    36、冒泡排序

    比较相邻的元素,如果前者比后者大,则交换,大的在右边,双重循环,最外层循环arr.length - 1,内层循环比较相邻两个数的大小,直到吧最大的数放在最右边,外层循环arr.length-1次,然后数组就会从小到大排列。

    37、快排排序

    一个数组里面寻找中间的值作为基准,然后创建两个空数组,循环原数组,将数组的每个值跟基准比较,比基准小的存在一个数组,比基准大的存在一个数组,然后递归执行以上操作,最后将两个数组合并。

    38、为什么要清楚浮动,如何清除?

    当给元素设置了浮动float过后,就会产生高度塌陷的情况,就是如果子元素高度大于父元素时,父元素就包含不住子元素了。

    • 给父元素添加伪元素清楚浮动
    .clear-float:after{
       display:block;
       content : "";
       clear:both;
       height:0
    }
    
    • 父级盒子触发BFC

    39、实现数组去重

    • 使用indexOf()去重,首先创建一个空数组,然后原数组循环遍历,然后判断如果当前的这个值在创建的新数组里面没有,也就是等于-1,那么就添加,如果有,则不添加。
     let res = []
        for (let i = 0; i < arr.length; i++) {
            if (res.indexOf(arr[i]) === -1) {
                res.push(arr[i])
            }
        }
    
    • 使用ES6,Set去重
    const arr = [1,2,2,3,4,5,3]
    console.log(new Set(arr))
    

    40、谈一谈箭头函数

    • 箭头函数可以更改this的指向,使this指向上下文
    • 箭头函数后面只要一条语句时,可以直接写在后面
    • 箭头函数需要返回一个对象时,则需要使用({})

    41、谈一谈ES6中的模块化

    ES6的模块化分为导出(export)与导入(import)两个模块。如果希望外部能读取模块当中的内容,就必须使用export暴露出去,然后在另外一个文件中用Import引入该模块,一个模块如果只有一个默认导出的话,就使用export default,引入的时候也可使用as进行重命名。

    42、JS原型链和原型

    • prototype是函数才有的属性
    • __proto __是每个对象都有的属性
      当我们定义一个函数的时候,就会产生一个原型对象,当我们使用这个函数构造对象,该对象都会从原型对象中继承属性、方法。
      当JS寻找该对象的属性时,先会查找对象本身是否存在该属性,如果不存在,则会在原型链上查找。
      因为任何对象都有proto,所以会形成一个链条,当我们到顶点的时候,就会发现proto里面只有object了,因为JS中任何对象都是Object的实例。

    43、使用原型链实现js继承

    • 思路就是让子类的原型等于父类的实例,因为父类的实例,就继承了父类的属性和方法,然后父类的属性和方法就定义在子类的原型对象上,这样子类就实现了继承父类
     //父方法
      function SupperFunction(flag1){
        this.flag1 = flag1;
      }
    
      //子方法
      function SubFunction(flag2){
        this.flag2 = flag2;
      }
    
      //父实例
      var superInstance = new SupperFunction(true);
    
      //子继承父
      SubFunction.prototype = superInstance;
    
      //子实例
      var subInstance = new SubFunction(false);
    
      //子调用自己和父的属性
      console.log(subInstance.flag1);
      console.log(subInstance.flag2);
    

    44、Vue组件间的通信

    • 通常父组件传递给子组件使用props
    • 子组件传递给父组件,使用ref属性,获取真实dom
    • 子组件使用emit方法
    • 使用vux

    45、介绍Vuex

    vuex能对vue项目进行状态管理,主要一般通过state,mutations,action这三个模块构造,state是保存所有数据,mutations用来保存所有方法,用来改变state的数据,action一般暴露给用户使用,可执行异步操作,用来触发mutatios的方法,用来改变数据。一般在页面中通过mapState来读取数据,通过mapActions来操作action。面对复杂的应用我们还需要创建modules,将vuex的store对象拆分成模块来写。

    46、vuex的优缺点

    优点首先是

    • 代码看得更简洁了,我们阅读代码时,不需要去看组件之间如何传递数据的,特别是非父子组件传递
    • 减少了ajax请求,可以从store里面直接取
      缺点:
    • 每次刷新vuex也就会刷新,但是我一般需要长久存储的数据,我会存储在localStorage里面,然后vuex再读取。

    47、vue双向数据绑定原理

    实现双向数据绑定主要是结合发布者-订阅者的模式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发给订阅者,触发相应的监听回调,当把一个普通的对象作为data选项时,vue将遍历它的属性并且转换为getter/setter。

    48、sum求和,可以传入多个参数

    使用arguments这个API,arguments为函数传入的实参,并且会转换为数组形式,这样的话就好做了,遍历实参,相加,最后返回。

    49、多维数组降为一维数组

    将数组转换为字符串,再切割字符串

    let arr = [1, 2, 3, 4, 5, [6, 7, 8, [9, 10, 11, 12, [13, 14, 15, 16]]]]
    console.log(arr.toString())  
    let newArr = arr.toString().split(',')
    console.log(newArr)  
    

    50、什么是TCP

    OSI一共有7层网络模型,应用层、表示层、会话层、传输层、网络层、数据链路层、物理层,TCP和UDP是传输层的协议。
    TCP无论哪一方向另一方发送数据之前,都会在双方之间建立一条连接。连接是通过“三次握手”进行初始化的。三次握手的目的是建立可靠的通信连接,确认双方的发送与接收是否正常。完成了三次握手,客户端和服务端就可以开始传送数据了。
    三次握手的步骤

    • 第一次握手,客户端发送请求建立连接,请求报文段
    • 第二次握手,服务器收到请求,发送同意并请求与客户端建立连接
    • 第三次握手,客户端收到请求,发送同意与服务器建立连接
      当客户端与服务器通过三次握手建立了TCP连接过后,当数据传送完毕,相应的就要断开TCP连接了,于是就有了四次分手的步骤。
      四次分手的步骤
    • 第一次分手,客户端发送断开请求
    • 第二次分手,服务器收到断开请求,发送同意断开连接的请求
    • 第三次分手,服务器发送请求断开连接
    • 第四次分手,客户端收到,发送同意断开连接

    51、为什么TCP是三次握手,而不是两次

    可能会形成死锁。假设客户端给服务器发送了一个连接请求报文,服务端成功接收并给客户端发送了确认应答报文,此时服务端并不能确认该应答报文是否成功到了客户端,但因为两次握手,所以这时候服务端就处于成功连接的状态了,并给客户端发送数据。如果客户端未收到服务端的应答报文,则不知道服务器是否确认好建立连接,甚至不知道自己发送给服务器的报文是否成功抵达,此时客户端会认为连接并未成功建立,会忽略服务端发送过来的任何数据。而服务端发送的数据未得到相应超时时,会重复发送同样的数据,这样就形成了死锁。

    52、TCP和UDP的区别

    TCP是一种面向连接,可靠稳定的传输协议,建立连接需要经历三次握手,握手成功才可通信,但是速度比较慢,效率比较低,容易被DOS,DDOS攻击。
    UDP是一种面向无连接,不可靠的传输协议,会直接建立连接,速度快,没有三次握手的机制,所以会相对安全,但是UDP还是可能会被flood攻击,在网络不好的情况,容易发生丢包。

    • 当对网络通信质量有要求时,比如:整个数据要准确无误的传递给对方,这往往对于一些要求可靠的应用,比如HTTP,HTTPS,FTP等传输文件的协议,POP,SMTP等邮件的传输协议。常见使用TCP协议的应用:
      1.浏览器使用的:HTTP
      2.FlashFXP:FTP
      3.Outlook:POP,SMTP
      4.QQ文件传输
      UDP 文件传输协议
    • 对当前网络通讯质量要求不高的时候,要求网络通讯速度尽量的快,这时就使用UDP
      日常生活中常见使用UDP协议:
      1.QQ语音
      2.QQ视频

    HTTP请求报文

    HTTP的请求报文包括:请求行(request line)、请求头部(header)、空行 和 请求数据(request data) 四个部分组成。

    • 请求行包括: 请求方法,URL(包括参数信息),协议版本这些信息
    • 请求头部(Header)
    • 空行(CR+LF):请求报文用空行表示header和请求数据的分隔
    • 请求数据:GET方法没有携带数据, POST方法会携带一个body

    浏览器渲染的步骤

    • 处理HTML标记并构建DOM树
    • 处理CSS标记并构建CSSOM树
    • 将DOM与CSSOM合并成一个渲染树
    • 根据渲染树来布局,计算每个节点的布局信息
    • 将各个节点绘制到屏幕上

    53、输入url后发生了什么

    • 用户输入url通过DNS解析为对应的IP地址
    • TCP连接
    • 发送http请求
    • 返回http响应
    • 浏览器解析渲染页面
    • 断开TCP连接

    54、重绘和重排的区别

    重绘不一定重排,重排必定导致重绘

    • 重绘:指一个元素外观被改变,浏览器会根据元素新属性重新绘制,使元素呈现新的外观,比如改变某个元素的背景色、文字颜色、边框颜色等
    • 重排 :当渲染树的一部分更新并且节点的尺寸发生了变化,浏览器会使渲染树种受到影响的部分失效,并且重新构造渲染树。
      引发重排
      1、添加、删除可见的dom
      2、元素的位置改变
      3、元素的尺寸改变
      4、页面渲染初始化
      5、浏览器窗口尺寸改变
      优化
      浏览器会维护一个队列,把所有引起重拍、重绘的操作放入这个队列,等队列到了一定的数量或者到了一定的时间间隔,浏览器就会进行处理,这样多次重排重绘就会进行成一次重排重绘
    • 不要一条一条修改dom样式,写在定义好css的class中
    • 为动画元件使用绝对定位,修改样式就不会进行重绘

    54、HTML行内元素、块状元素、行内块状元素的区别

    使用display可以将三者任意转换,

    • 行内元素,最常用的就是span
      (1)、设置宽高无效
      (2)、margin仅左右有效
      (3)、不会自动换行
    • 块状元素,具有代表性的就是div
      (1)、能够识别宽高
      (2)、margin和padding均有效
      (3)、可以自动换行
    • 行内块状元素
      (1)、能够识别宽高
      (2)、不会自动换行
      (3)、默认排列方式从左到右

    55、http和https的区别

    https的ssl加密是在传输层实现的

    • http传输的数据都是未加密的,而https是通过ssl协议对数据进行加密处理
    • https协议需要ca证书,费用较高
    • http协议的端口为80,而https协议端口为443

    56、移动端怎么做适配的

    • 使用viewport,随着屏幕宽度变化,页面也会跟着变化
    <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">
    

    width设置成了设备的宽度,initial-scale控制了页面加载时候的缩放等级,maximum-scale为用户最大缩放值,user-scalabel是否允许用户进行缩放

    57、box-sizing属性

    box-sizing是更改盒子模型基准,有两个选项,一个是content-box,一个是border-box。还有一个是inherit默认的是content-box。
    其实两者的区别也就是盒子的宽高是否包含border和padding,如果是content-box那么宽高就是固定的,如果是border-box,那么宽高就是设定的宽高再减去border和padding,就是这个盒子的宽高。
    inherit是继承父元素的box-sizing。

    58、宏任务与微任务

    宏任务例如,script,setTimeout,setInterval
    微任务例如Promise.then
    执行一个宏任务,执行过程中如果遇到微任务,就会将微任务添加到微任务的队列,宏任务执行完毕过后,会立即按顺序执行微任务,当这个宏任务执行完毕后,开始进行渲染,渲染完毕后,开始下一个宏任务。

    59、BFC是什么?

    BFC是块级格式化上下文,是用于布局块级盒子的一块渲染区域。
    一般触发BFC的条件

    • 根元素,即html元素
    • float的值不为none
    • overflow的值为hideen
    • display的值为inline-block
    • position的值为absolute或者fixed
      作用
    • 可以阻止元素被浮动的元素覆盖
    • 清除浮动
    • 解决同一个BFC区域的垂直方向margin塌陷的问题
      属于同一个BFC的两个相邻的box的margin会重叠,以大的为主。要想解决这个问题,可以将两个盒子分为不同的BFC中。

    60、AST抽象语法树

    抽象语法树,是源代码的抽象语法结构的树状表现形式,一般指编程语言的源代码

    61、put、post、patch的区别

    post用来创建资源,多次执行,会导致多条资源重复创建
    put一般用来更新已知资源
    patch对已知资源进行局部更新

    62、vue-router原理

    vue-router是应用在单页面应用中。
    单页面:第一次进入页面的时候会请求一个html文件,当url变化时,js会感知到,js会将当前的页面清除掉,判断当前url需要显示哪个组件,清除不需要的,显示需要的组件。
    实现原理:更新视图但不重新请求页面
    前端路由主要有两种模式,hash模式和history模式,hash会在域名后面加一个#号,hash虽然会出现在url中,但不会包括在http请求中而history则不存在,没有#号,这种模式需要服务端支持。服务端接收到请求后,都指向同一个html文件。
    vue-router也是利用了这两个特性来实现前端路由

    63、Node.js中间件

    中间件主要是指封装所有http请求细节处理的方法,比如记录日志、权限验证、异常处理等。
    中间件是从http请求发起到响应结束过程中的处理方法,通常需要对请求和响应进行处理。

    64、什么是DNS、FTP,基于什么协议?

    DNS(Domain Name System):域名解析协议,端口号:53;通过域名解析获得域名所对应的IP

    FTP(File Transfer Protocol):文件传输协议,端口号:21;用户可通过客户机程序向远程主机上传文件;或从远程主机上下载文件。

    • FTP用的TCP协议。
    • DNS域名解析时用的UDP协议,DNS区域传输的时候使用的TCP协议。
      辅域名服务器会定时(一般3小时)向主域名服务器进行查询以便了解数据是否有变动,这就是区域传输。

    65、Vue生命周期

    beforeCreate : 组件创建之前
    created:组件创建后
    beforeMount:组件挂载之前
    mounted:挂载完成
    beforeUpdate:数据更新前
    updated:数据更新后
    beforeDestory:实例销毁之前
    destored:实例销毁后

    65、防抖和节流

    防抖:让某个时间期限内,事件处理函数只执行一次,例如获取滚动条位置,就要每3S执行一次,可以使用定时器来实现,我们可以在一个方法里面使用闭包来存储一个状态,定时器每次执行,都会返回一个类似于ID,ID是用来关闭定时器的,每次执行该方法,如果有ID就清除该ID的定时器,并且创建一个新的定时器。

    function dbbounce(fn,delay){
            let timer = null
            return function(){
                //setTimeout每次执行,会返回给我一个特殊的值,这个值是用来关闭定时器的,每次执行该方法时,如果有timer就清楚上个定时器
                //如果没有就执行定时器
                if(timer){
                    clearTimeout(timer)
                }
                timer = setTimeout(fn,delay)
            }
        }
    
        function showTop (){
            var scrollTop = document.documentElement.scrollTop
            console.log('滚动距离',scrollTop)
        }
    
        window.onscroll = dbbounce(showTop,3000)
    

    节流:函数执行一次后,在某个时间段内暂时失效,过段时间再重新激活,使用闭包存储一个布尔类型的状态,每次执行该方法时,如果状态为false则不执行,如果状态为true,则会使状态先等于false,达到冷却的效果,再调用定时器,定时器完成过后,会将状态改为true。

     function throttle(fn, delay) {
            let valid = true
            return function () {
                //类似于技能能却,执行完一次,有间隔时间,时间走完了,才能再执行
                //滚动时,如果状态为false就不执行,如果状态为true,在间隔期间设置状态为false,然后在执行定时器,定时器执行完,将状态改为true
                if (!valid) {
                    return false
                }
                valid = false
                setTimeout(() => {
                    fn()
                    valid = true
                }, delay)
    
            }
        }
    
        function showTop() {
            var scrollTop = document.documentElement.scrollTop
            console.log('滚动距离', scrollTop)
        }
    
        window.onscroll = throttle(showTop, 2000)
    

    66、ajax,axios和fetch有什么区别

    ajax

    • 本身针对MVC的编程,不符合现在MVVM的框架
    • JQuery整个项目太大,单纯使用ajax却要引入整个JQuery
      axios
    • 支持Promise语法
    • 客户端支持防止CSRF
    • 拦截请求头和响应
    • 自动转换json数据
      fetch
    • fetch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理。

    67、为什么JS是单线程的?

    JS作为浏览器脚本语言,JS的主要用途是与用户互动,以及操作DOM。这决定了只能是单线程,否则会带来复杂的同步问题,比如,假如JS有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时候浏览器就不知道应该以哪个为准。

    68、路由懒加载

    路由懒加载也叫按需加载,即在需要的时候进行加载,单页应用,利用webpack打包后的文件会非常大,造成进入首页时,需要加载的内容过多,时间过长,会出现长时间白屏,而运用懒加载可以将页面进行划分,需要的时候加载页面,减少首页加载用时。

    routes: [
        {
          path: "/",
          name: "home",
          component: Home
        },
        {
          path: "/about",
          name: "about",
          component: () => import(/* webpackChunkName: "about" */ "./views/About.vue")
        }
      ]
    
    

    69、前端项目优化

    • 路由懒加载
    • 开启nginx的gzip压缩
    • 抽取公用组件和方法,清除冗余代码
    • 使用压缩工具压缩图片,例如tinypng

    72、水平垂直居中

    • flex布局, justify-content: center; align-items: center;

    • 给父元素设置相对定位,给子元素设置绝对定位

     #father {
            width: 500px;
            height: 300px;
            background-color: skyblue;
            position: relative;
    }
     
        #son {
            background-color: green;
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translateX(-50%) translateY(-50%);
    }
    
    

    73、两个等号和三个等号的区别

    • 三个等号称为等同符,当两边值类型相同时,直接比较值,若类型不相同,直接返回false
    • 两个等号称为等值符,当等号两边类型相同时,直接比较值,若不相同,则先转化为类型相同的值,在进行比较。
      类型转换规则:
      (1)如果等号两边是boolean、string、number三者中任意两者进行比较时,优先转换为数字进行比较。
      (2)如果等号两边出现了null或undefined,null和undefined除了和自己相等,就彼此相等

    74、常用操作字符串方法

    • split(sep,limit):将字符串分割为字符数组,limit为从头开始执行分割的最大数量
    • slice(start,end):返回字符索引在start和end(不含)之间的子串
    • substr(start,length):从字符索引start的位置开始,返回长度为length的子串
    • substring(from,to):返回字符索引在from和to(不含)之间的子串
    • charAt(index):返回指定索引处的字符串
    • charCodeAt(index):返回指定索引处的字符的Unicode的值
    • lastIndexOf(str):返回str在父串中最后一次出现的位置,若没有则返回-1
    • indexOf(str):返回str在父串中第一次出现的位置,若没有则返回-1

    75、常用操作数组方法

    • push(),向数组的末尾添加元素
    • pop(),删除数组中最后一个元素
    • unshift(),向数组开头添加元素
    • shift(),删除数组第一个元素
    • splice(index,howmany,item1....):添加/删除数组元素,index规定位置,howmany为删除的数量,item1......可选向数组添加的新项目
    • sort(),对数组元素进行排序,并返回这个数组,sort的比较函数有两个参数,返回a-b则使升序,返回b-a则是降序
    • slice(start,end):返回数组下标在start和end(不含)之间的值
    • indexOf() 查找数组是否存在某个元素,返回下标
    • lastIndexOf() 查找指定元素在数组中的最后一个位置
    • includes() 查找数组是否包含某个元素 返回布尔
    • filter(function) 过滤原始数组,返回新数组
      function(currentValue,index,arr): 数组中每个元素需要调用的函数。
      // 回调函数的参数
    1. currentValue(必须),数组当前元素的值
    2. index(可选), 当前元素的索引值
    3. arr(可选),数组对象本身

    76、什么是事件委托

    事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
    当我们有很多dom需要添加处理事件,比如ul下面有很多li,我们给每个li都要添加相同的点击事件,通常会用for循环,给它们添加点击事件,这有很大的性能弊端

    77、call、bind、apply的区别?

    • bind 返回一个函数, 第一个参数是改变this指向的对象 直接传参
    • apply 对函数的直接调用, 第一个参数是改变this指向的对象 参数用数组包裹
    • call 对函数直接调用,第一个参数是改变this指向的对象 直接传参

    78、深拷贝和浅拷贝的区别

    它们最根本的区别在于是否真正获取了一个对象的复制实体,而不是引用
    浅拷贝现在可以使用Object.assign快速实现
    Object.assign()只有源对象,没有目标对象时为浅拷贝
    JSON.parse(JSON.stringify())可以实现深拷贝

    79、JSON.parse和JSON.stringify的区别

    • JSON.parse()【从一个字符串中解析出json对象】
    • JSON.stringify()【从一个对象中解析出字符串】

    80、JS动画和CSS3动画差异性

    css3后来添加了transform动画函数
    css3动画与js动画的区别:
    js功能涵盖面比css3广
    css3比js更易实现
    css3存在兼容问题 js不存在兼容问题

    81、join("")和toString()的区别

    join(“”)转换为字符串时,会将逗号去掉

    82、JS基本数据类型

    基础类型:Undefined,Null,Boolean,Number,String,Symbol
    引用类型:Object,Array
    symbol生成的是一个全局唯一的值,Symbol(1) === Symbol(1)是为false的。

    83、ES6新特性

    • promise
    • async/await
    • class
    • 箭头函数
    • 扩展运算符

    84、谈谈ES6中的class

    首先class是用来创建类的,在传统的js中,没有类的概念。class的作用让原型对象的写法更加清晰

    • 首先我们在类里面写方法时,方法时直接定义在原型对象上面
    • constructor就相当于构造函数,接受参数
    • 类必须使用new调用

    85、扩展运算符

    扩展运算符就是遍历目标对象,拷贝到当前对象中
    扩展运算符如果目标对象中含有引用数据类型,则使用扩展运算符拷贝出来的则是浅拷贝。

    86、vue和react的事件绑定对比

    首先vue的特色是双向绑定,而react是单向绑定,其实vue的双向绑定也可以使用单向绑定加上onChange事件监听来实现。

    87、Hooks是什么

    原来我们写一个组件需要去声明一个类,但是使用了hooks就不需要了,就直接使用function创建一个函数,然后使用useState来管理状态,然后在返回html模板就可以成功创建一个组件了

    88、webpack是什么,loader是什么?

    webpack是前端构建的一个工具,loader其实就是提供了打包方案,就比如webpack不知道怎么打包图片模块、css模块、js模块时,就会使用各种loader来帮助Webpack打包
    比如:
    image-loader:加载并且压缩图片文件
    babel-loader:把 ES6 转换成 ES5
    css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
    eslint-loader:通过 ESLint 检查 JavaScript 代码

    plugin其实主要是监听一些webpack事件的,然后做优化

    89、CSS可继承的属性

    1、字体系列属性,例如字体粗细,风格,大小
    2、文本系列属性,例如行高,文本颜色
    无继承的属性:display,背景属性,盒子模型的属性,定位属性

    谈一谈RCM自动升级这个项目?

    公司每次有升级包,就需要在这创建任务,上传升级包,然后对任务可视化操作,显示进度和状态信息等,可以编辑,可以查看详情,可以下载对比文件等,除此之外还有一些基准文件配置、邮箱配置、常用工具等功能。
    1、表单联动太多,开始想着用change方法来监听数据,最后编辑的时候,因为需要初始化数据,最后才采用的watch的深度监听
    2、formdata传递数组,当时后端需求就是我需要传一个数组,这个数组每一个对象里面都包含的有文件,所以我选择采
    用Formdata形式传递数据给后台,而formdata添加数据又是key,value的形式,所以我添加时key就是将数组转为语义化来命名。
    3、下载浏览器默认打开的文件。

    谈一谈你做项目遇到的困难

    1、最开始做项目的时候,跨域问题以及服务器配置
    2、前期对数据的处理,例如数组,或者对象类型的方法了解的太少

    相关文章

      网友评论

          本文标题:2020前端面试

          本文链接:https://www.haomeiwen.com/subject/ygituktx.html