2022高频前端30道面试题汇总

271 阅读10分钟

1.当在浏览器中输入URL的时候,发生了什么?

(1)浏览器分析链接指向的URL

(2)浏览器向DNS请求解析链接的IP地址

(3)DNS服务器解析出IP地址

(4)浏览器与该服务器建立TCP连接

(5)浏览器发出HTTP请求

(6)服务器通过HTTP响应把文件发送给浏览器

(7)释放TCP连接

(8)浏览器解释文件,并将web网页显示给用户

2.如何解决跨域问题?什么是同源策略?

同源指的是:协议+域名+端口号相同;

常用解决跨域的问题有3种方案

1.jsonp的方式解决跨域

利用script标签没有跨域限制,通过script标签的src属性,发送带有callback参数的get请求。

2.跨域资源共享(CORS)

3.nginx代理跨域

3.如何理解this?

this表示的是函数运行时自动生成的一个内部对象,只能在函数内部使用,总是指向调用它的对象。

this是在运行时进行绑定的,并不是在编写的时候绑定,它的上下文取决于函数调用时的各种条件。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。

4.浏览器的多进程和javaScript的单线程

一个进程是由一个或者多个线程组成的,线程是一个进程中代码的不同执行路线。一个进程的内存空间是共享的,所有的线程都能够访问这些内存。打开一个tab页,其实就是创建了一个进程,一个进程可以有多个线程,比如JS引擎线程、GUI渲染线程、HTTP请求线程、定时器触发线程、事件触发线程等。当发起一个请求的时候,其实就是创建了一个线程。当请求结束时,线程可能就会销毁。

JavaScript的单进程与它的用途有关,作为浏览器的脚本语言,javaScript主要是和用户互动,以及操作DOM。如果有两个线程同时操作DOM的话。会带来很复杂的同步问题。

5.事件循环

事件循环的异步队列有两种:一种是宏任务,一种是微任务。宏任务队列可以有多个,微任务队列只有一个。

所有的同步任务都在主线程上执行,形成“执行栈”。首先主线程会去执行所有的同步任务,等所有的同步任务执行完,会查看任务队列里面的异步任务。如果满足条件,那么就重新进入主线程开始执行,这时它就变成了同步任务。等它执行完后,下一个异步任务会进入到主线程开始执行。直到所有的任务执行结束。

第一次事件循环中,js引擎会把整个script代码当成一个宏任务执行。执行完成之后,会查看任务中是否存在微任务,如果有微任务,那么会依次从微任务的队列中将读取执行完所有的微任务。执行完微任务之后,js引擎会继续查看宏任务队列中的任务,依次执行。再执行微任务队列。如此循环。

6.hash路由和history路由

hash(#)是URL的锚点,代表网页中的一个位置,单是改变hash(#)后面的部分,只会滚动到网页响应的位置,并不会重新刷新页面。也就是说hash出现在URL中,但不会被包含在http请求中。因此改变hash不会重新加载页面。同时每一次更改#后面的部分就会在浏览器的历史记录中添加一条数据,使用浏览器的后退按钮就能返回到上一个位置。hash模式通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据。

监听hash的改变通过==》hashchange()

histoy模式利用了h5中history interface新增的pushState()和replaceState(),提供了对浏览器记录栈修改的功能,当它们执行修改时,虽然会改变URL,但是不会立即向后端发送请求。这种情况需要后台配置支持。我们的页面时SPA,如果后台没有相应的配置,用户直接访问其中一个页面的时候就会404。在服务端增加一个覆盖所有资源的默认情况。URL如果匹配不到相应的资源,那么返回一个index.html页面。这个页面就是app依赖的页面。

7.性能优化

浏览器缓存、cdn加速、重绘回流、webpack性能优化、网络优化、减少http请求。

8.防抖和节流的区别

防抖:n秒后执行该事件,若在n秒内重复触发,则会重新计时。

节流:n秒内只运行一次,若在n秒内重复触发,只有一次生效。

9.深拷贝和浅拷贝的区别?

浅拷贝是拷贝一层。属性为对象时,那么浅拷贝是复制,两个对象会指向同一个地址。

深拷贝是递归拷贝深层次,属性为对象时,深拷贝是新开栈,两个对象指向的是不同地址。

如何实现浅拷贝

(1)Object.assign

(2)ES6的扩展运算符

(3)slice()

(4)concat()

如何实现深拷贝

(1)通过递归的方式实现

10.如何理解微前端(qiankun框架)?

微前端就是各个组件仓库相互独立,彼此之间独立开发,互不影响。通过通信进行沟通,整体对外提供一个服务。

11.undefine和Null的区别?

null表示没有对象,即此处不应该有值。转换成数值的时候为0

undefined表示缺少值,就是此处应该有一个值,但是还未被定义。转换为数值的时候为NaN

12.重绘和回流

重绘指的是渲染树中的属性发生改变。不影响布局,产生重绘。

回流指的是渲染树中的布局发生改变,产生重绘回流。

13.什么是闭包和闭包需要注意的问题?

闭包是指有权访问另一个函数作用域中变量的函数。

需要注意内存泄漏

14.为什么使用hook

(1)难以重用和共享组件中的与状态相关的逻辑

(2)函数组件是无状态的,由于业务变动,函数组件不得不改变成类组件

(3)类组件中的this增加学习成本

15.项目的亮点和难点在哪?

因人而异,做好平时项目的复盘和总结。

16.如何理解继承?

子类具有父类的属性和方法。

实现方式有原型链继承、构造函数继承、组合继承、寄生式继承、原型继承、寄生组合式继承

17.什么是HTTP?HTTP和HTTPS的区别

HTTTP是超文本运输协议,是实现网络通信的一种规范。

http是无状态的,也就是说http无法根据上一次的状态进行本次的请求处理,每次都需要重新建立tcp连接

http和https的区别:https更加安全,http是采用明文传输的,这并不安全。https和http的连接方式不同,端口号也不同,http的端口号是80,https的端口号是443。https需要ssl证书,功能越强大价格越贵。

18.HTTP的状态码?

1XX:指示信息,表示请求已接收,继续处理

2XX:成功的状态码

3XX:重定向

301:表示永久重定向

302:临时重定向

304:未修改,重定向到浏览器。

4XX:客户端错误

401:表示发送的http请求需要有http的认证信息

404:表示未请求到相应的资源

403:表示对请求资源的访问被服务器拒绝

400:请求报文存在语法错误

5XX:服务器错误

500:表示服务器在执行请求的时候发生了错误

501:表示服务器不支持当前请求所需要的某个功能

503:表示服务器处于超负载或者停机维护,无法提供服务

19.HTTP2和HTTP的区别

Http1.x会有队头阻塞的问题。浏览器限制了同一域名下的请求数量,当http的请求达到最大请求数量时,剩余的资源需要等待请求其他资源请求完成之后才能发起请求。

Http2中新增了两个新的概念,一个是帧,一个是流。帧代表最小的数据单位,帧会识别出该帧属于哪个流。流就是多个帧组成的数据流。http2采用二进制传输、多路复用(就是在tcp连接中可以存在多个流,也就是可以发送过个请求,这个技术解决了队头阻塞的问题。)、服务端可以在客户端发送请求之后,主动推送一些资源、header压缩。

20.HTTP的缓存机制

http的缓存分为两种,协商缓存和强制缓存。两者都是通过http响应头控制缓存。

强制缓存:再次请求的时候不会向服务器发送请求

协商缓存:再次请求的时候,服务器会校验资源是否更新,如果未更新,则返回304,从浏览器获取资源。

21.如何取消请求的发送

根据发送网络请求的api不同,取消方法不同

xhr、fetch、axios

如果使用XMLHttpRequset,则使用XMLHttpRequset.abort();

如果使用fetch或者axios则使用AbortController

22.cookie、seesionStorage和localStorage有何区别?

localStorage的生命周期是永久的除非主动清除。而seesionStorage的生命周期是当前窗口或者标签页,关闭窗口或标签页则会清除数据。cookie数据始终在同源的http请求中携带(即使不需要)cookie的大小为4k。

均只能存储字符串类型的对象。

23.写Vue/React项目是在列表组件中写key,为什么?

vue和react都是通过diff算法来对比新旧虚拟节点,从而更新节点。在对比的过程中,会根据新节点的key对比旧节点数组中的key,从而找到相应的旧节点。如果没有找到就表示新增一个节点。如果没有key,那么就需要遍历的方式查找相应的旧节点。

24.computed和watch的区别?

computed是计算属性,依赖其他属性值,并且computed的值具有缓存。只有他依赖的属性值发生改变,下一次获取computed的值时,才会重新计算computed。

watch是监听,每当数据发生变化的时候都会执行回调函数进行后续操作。

25.v-if和v-show的区别是什么?

v-show 总是会进行编译和渲染的工作 - 它只是简单的在元素上添加了 display: none; 的样式。v-show 具有较高的初始化性能成本上的消耗,但是使得转换状态变得很容易。 相比之下,v-if 才是真正「有条件」的:它的加载是惰性的,因此,若它的初始条件是 false,它就不会做任何事情。这对于初始加载时间来说是有益的,当条件为 true 时,v-if 才会编译并渲染其内容。切换 v-if 下的块儿内容实际上时销毁了其内部的所有元素,比如说处于 v-if 下的组件实际上在切换状态时会被销毁并重新生成,因此,切换一个较大 v-if 块儿时会比 v-show 消耗的性能多。

26.有没有用npm发布过package,如何发布?

1.注册 npm 账号 www.npmjs.com/

2.本地通过命令行 npm login 登陆

3.进入到项目目录下(与 package.json 同级),在 package.json 中指定发布文件、文件夹

27.如何将类数组转换成数组?

Array.from()

Array.apply(null, array)

Array.prototype.concat.apply([], array)

28.如何剪裁图片(选择头像)

q.shanyue.tech/fe/js/231.h…

29.bind 与 call/apply 的区别是什么

他们都是绑定 this 的,但是bind 返回函数,call/apply 直接执行函数

30.数组扁平化

使用flat

使用reduce

使用递归