2021前端面试题理论知识总结(进阶版)

173 阅读13分钟

1.两种盒模型
w3c的盒子模型 width = width + border + padding
IE的盒子模型 width = width
一般都使用标准的w3c盒子模型,如果需要使用IE的盒子模型,可以使用box-sizing属性进行修改

2.移动端Web页面适配方案
早期网页设计采用静态布局
后面出现流式布局
使用百分比%定义宽度,高度使用px固定 再后来出现了弹性布局 em/rem/rpx做单位

3.CSS3伪类和伪元素的特性和区别
伪类::active :hover :link 等
伪元素: :atter :before :frist-letter 等
区别:
伪类本质上是为了弥补常规CSS选择器的不足,以便获取到更多信息;
伪元素本质上是创建了一个有内容的虚拟容器;
CSS3中伪类和伪元素的语法不同;
可以同时使用多个伪类,而只能同时使用一个伪元素;

4. 什么是BFC
BFC直译为“块级格式化上下文”,可以理解成:创建了 BFC的元素就是一个独立的盒子,里面的子元素不会在布局上影响外面的元素
属于同一个BFC的两个相邻Box的margin会发生重叠,
处理方法:
在div外面包裹一层容器,并触发该容器生成一个BFC BFC作用:
防止外边距重叠,清除浮动的影响
如何创建BFC
1)根元素
2)float属性不为none
3)position不为static和relative
4)overflow不为visible
5)display为inline-block, table-cell, table-caption, flex, inline-flex

5.link和@import的区别
这两种方式都是为了加载css文件,但还是存在细微的差别
差别:
老祖宗的差别,link属于XHTML标签,而@import完全是css提供的一种方式。link标签除了可以加载css外,还可以做很多其他的事情,比如定义RSS,定义rel连接属性等,@import只能加载CSS。
加载顺序的差别:link引用的CSS会同时被加载,而@import引用的CSS会等到页面全部被下载完再加载 兼容性的差别:@import只有在IE5以上的才能识别

6.this永远指向的是最后调用它的对象(具体参看自家文本或百度)

7. 判断数据类型
1、typeof
2、instanceof
[] instanceof Array;// true
{} instanceof Object;// true
3、constructor [].constructor == Array
4、toString
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number] 后面自己判断吧

8.Promise

Promise 是一种异步函数
let promise = new Promise(function(resolve, reject){ console.log("AAA"); resolve() }); promise.then(() => console.log("BBB")); console.log("CCC")
// AAA 在Promise新建后会立即执行
// CCC
// BBB
优缺点
优点:解决回调、链式调用、减少嵌套
缺点:无法监测进行状态、新建立即执行且无法取消、内部错误无法抛出 多次调用异步可以用async await 就可以不需要一直使用then

9.垃圾回收机制
Js具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。
JS中最常见的垃圾回收方式是标记清除。
工作原理:是当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。

10.内存泄漏
js的垃圾回收机制就是为了防止内存泄漏的,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着
如果在mounted/created 钩子中绑定了DOM/BOM 对象中的事件或使用了第三方库初始化或组件中使用了定时器,需要在beforeDestroy 中做对应解绑销毁处理

11. JS事件机制:事件触发JS函数
1)、单双击事件: 单击:onclick 双击:ondblclick
2)、鼠标事件:onmouseover onmousemove onmouseout
3)、键盘事件: onkeyup onkeydown
4)、焦点事件: onfocus onblur
5)、页面加载事件: onload

12.错误定位
1.看报错信息
2.代码console调试
3.用window.onerror做调试

13.对象
对象是什么。简言之,包含属性和方法的就是对象。属性是静态的,通常写在构造函数中,方法是动态的,公用的,通常写在原型中

14.面向对象基本特征:封装 继承 多态
对象实例化方式: 原始模式 工厂模式 构造函数模式

15.虚拟dom的概念
可以把Virtual DOM 理解为一个简单的JS对象,并且最少包含标签名( tag)、属性(attrs)和子元素对象( children)三个属性

虚拟 DOM 实现原理
用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象 用diff比较两棵虚拟 DOM 树的差异 用pach将两个虚拟 DOM 对象的差异应用到真正的 DOM 树

16.虚拟DOM+diff为什么快
1.真实DOM的创建需要完成默认样式,挂载相应的属性,注册相应的监听事件,如果元素比较多的时候,还涉及到嵌套,效率更低。 diff算法对DOM进行原地复用,减少DOM创建性能耗费
2.虚拟DOM很轻量,对虚拟DOM操作快
3.页面的排版与重绘也是一个相当耗费性能的过程。通过对虚拟DOM进行diff,逐步找到更新前后vdom的差异,然后将差异反应到DOM树上(也就是patch)减少过多DOM节点排版与重绘损耗
虚拟DOM+diff的缺点
(1)尺寸 更多的功能意味着更多的代码。
(2)内存 虚拟DOM需要在内存中的维护一份DOM的副本
(3)不是适合所有情况 如果一个DOM节点相对较少页面,用虚拟DOM,它实际上有可能会更慢

17.Vue2与Vue3的区别
1. vue2和vue3双向数据绑定原理发生了改变 vue2 的双向数据绑定是利用ES5 的一个 API Object.definePropert()对数据进行劫持 结合 发布订阅模式的方式来实现的。 vue3 中使用了 es6 的 ProxyAPI 对数据代理
2. 默认进行懒观察(lazy observation)。 在 2.x 版本里,不管数据多大,都会在一开始就为其创建观察者。当数据很大时,这可能会在页面载入时造成明显的性能压力。3.x 版本,只会对「被用于渲染初始可见部分的数据」创建观察者,而且 3.x 的观察者更高效。
3. 更精准的变更通知。 比例来说:2.x 版本中,使用 Vue.set 来给对象新增一个属性时,这个对象的所有 watcher 都会重新运行;3.x 版本中,只有依赖那个属性的 watcher 才会重新运行 4.默认项目目录结构也发生了变化 移除了 static 文件夹,新增 public 文件夹
5.使用上发生了改变

18.this.$nextTick()会等下次 DOM 更新循环之后执行

19.v-model 的原理
v-model 本质上不过是语法糖
text 和 textarea 元素使用 value 属性和 input 事件;
checkbox 和 radio 使用 checked 属性和 change 事件

20. 使用过 Vue SSR 吗?说说 SSR?
SSR大致的意思就是将标签渲染成 html 片段的工作在服务端完成,把服务端形成的html 片段直接返回给客户端这个过程就叫做服务端渲染
1)服务端渲染的优点:更好的 SEO 更快的内容到达时间(首屏加载更快,SSR 直接由服务端渲染好页面直接返回显示,无需等待下载 js 文件及再去渲染
2) 服务端渲染的缺点: 更多的开发条件限制:服务端渲染应用程序,需要处于 Node.js server 运行环境

21.vue-router 有 3 种路由模式:hash、history、abstract

22.能说下 vue-router 中常用的 hash 和 history 路由模式实现原理吗
1)hash 模式的实现原理
早期的前端路由的实现就是基于 location.hash 来实现的。其实现原理很简单,location.hash 的值就是 URL 中 # 后面的内容

**2)**history 模式的实现原理
HTML5 提供了 History API 来实现 URL 的变化。其中做最主要的 API 有以下两个:history.pushState() 和 history.repalceState()。这两个 API 可以在不进行刷新的情况下,操作浏览器的历史纪录

23.Proxy 与 Object.defineProperty 优劣对比
Proxy 的优势如下:
Proxy 可以直接监听对象而非属性;
Proxy 可以直接监听数组的变化
Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改
Object.defineProperty 的优势如下: 兼容性比较好

24.对于即将到来的 vue3.0 特性你有什么了解的吗?
(1)监测机制的改变 3.0 将带来基于代理 Proxy 的 observer 实现,提供全语言覆盖的反应性跟踪。这消除了 Vue 2 当中基于 Object.defineProperty 的实现所存在的很多限制 只能监测属性,不能监测对象 , 检测属性的添加和删除,检测数组索引和长度的变更等
(2)对象式的组件声明方式 vue2.x 中的组件是通过声明的方式传入一系列 option,3 .0 修改了组件的声明方式,改成了类式的写法,这样使得和 TypeScript 的结合变得很容易 vue3.0 也全面改用 TypeScript 来重写了,更是使得对外暴露的 api 更容易结合 TypeScript

25.了解 Componsition API 吗?
在 Vue2 中,代码是 Options API 风格的,也就是通过填充 (option) data、methods、computed 等属性来完成一个 Vue 组件。这种风格使得 Vue 容易上手,同时也造成了几个问题:
由于 Options API 不够灵活的开发方式,使得 Vue 开发缺乏优雅的方法来在组件间共用代码。 Vue 组件过于依赖this上下文,TypeScript 在 Vue2 中很不好用。 于是在 Vue3 中,舍弃了 Options API ,转而投向 Composition API。Composition API本质上是将 Options API 背后的机制暴露给用户直接使用,这样用户就拥有了更多的灵活性,也使得 Vue3 更适合于 TypeScript 结合

26.TypeScript和JavaScript的区别
基本数据类型不同 js 动态类型,运行运行时明确变量的类型,变量的类型由变量的值决定,并跟随值的改变而改变;ts 静态类型,声明时确定类型,之后不允许修改
js 直接运行在浏览器和node.js环境中;ts 编译运行,始终先编译成JavaScript在运行
js 弱类型,数据类型可以被忽略的语言。一个变量可以赋不同数据类型的值;ts 强类型,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了;

27. 使用TS的原因\好处
TS的设计目的应该是解决JS,弱类型和没有命名空间导致很难模块化,不适合开发大型程序的短处。
开源,跨平台。它本身不需要考虑运行环境的问题,所有支持JavaScript的地方都可以使用typescript;
引入静态类型声明,减少不必要的类型判断和文档注释;
及早发现错误,静态类型检查1或编译时发现问题,不用等到运行;
类、接口的使用更易于构建和维护组件;
重构更方便可靠,适合大型项目;

28.CSRF是什么
中文名称:跨站请求伪造,你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求
防御方法:
1.服务端在cookie加一个随机数
2.验证码

29.JS运行机制
‌**JavaScript(JS)的运行机制主要包括单线程模型事件循环机制任务队列以及宏任务微任务的分类和处理方式。**

单线程模型

JavaScript是一种单线程语言,这意味着在同一时间内只能执行一个任务。这种设计主要是为了简化编程模型,避免多线程带来的复杂性。单线程模型使得JavaScript在执行任务时不需要处理复杂的同步问题,尤其是在处理用户交互和DOM操作时显得尤为重要‌。

事件循环机制

为了在不阻塞主线程的情况下处理耗时操作,JavaScript采用了事件循环机制。事件循环机制将任务分为同步任务和异步任务。同步任务直接进入主线程执行,而异步任务则进入任务队列等待执行。当主线程上的同步任务执行完毕后,事件循环会从任务队列中取出异步任务执行。这个过程不断重复,形成了事件循环‌。

任务队列和任务分类

异步任务被进一步分为宏任务和微任务。宏任务通常是指那些执行周期较长、影响较大的任务,如setTimeoutsetInterval。微任务则是指那些执行周期较短、影响较小的任务,如Promise.thenasync/await。事件循环会优先执行所有的微任务,然后再执行一个宏任务,如此循环往复‌。

具体实现细节

在事件循环的过程中,同步任务会直接进入主线程执行。当遇到异步任务时,这些任务会被推送到任务队列中。主线程上的同步任务执行完毕后,事件循环会检查任务队列,优先执行所有的微任务,然后再执行一个宏任务。这个过程会不断重复,直到所有的任务都执行完

process.nextTick() 是一个特殊的异步API,其不属于任何的Event Loop阶段,Node在遇到这个API时会马上停下来执行process.nextTick() vm.nextTick用于将回调延迟到下次DOM更新周期之后执行。“下次DOM更新周期”的意思就是下次微任务执行时更新DOM,而vm.nextTick 用于将回调延迟到下次DOM更新周期之后执行。“下次DOM更新周期”的意思就是下次微任务执行时更新DOM,而vm.nextTick就是将回调函数添加到微任务中

30.请求状态
301 Moved Permanently:永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL
302 Found:临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL;
301与302的区别:前者是永久移动,后者是临时移动(之后可能还会更改URL)
303 See Other:表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源; 302与303的区别:后者明确表示客户端应当采用GET方式获取资源
304:所请求的资源未修改,服务器返回此状态码时,不会返回任何资源
400 Bad Request:表示请求报文中存在语法错误;
401 Unauthorized:未经许可,需要通过HTTP认证;
402 状态码(被403替代):支付失败
403 Forbidden:服务器拒绝该次访问(访问权限出现问题)
404 Not Found:表示服务器上无法找到请求的资源

31.前端缓存策略
浏览器端的缓存规则
对于浏览器端的缓存来讲,这些规则是HTTP协议头和HTML页面的Meta标签中定义的。他们分别从新鲜度和校验值两个维度来规定浏览器是否可以直接使用缓存中的副本,还是需要去原服务器获取更新的版本。
新鲜度(过期机制):也就是缓存副本有效期
校验值(验证机制):服务器返回资源的时候有时在控制头信息带上这个资源的实体标签Etag(Entity Tag),它可以用来作为浏览器再次请求过程的校验标识。如果发现校验标识不匹配,说明资源已经被修改或过期,浏览器需要重新获取资源内容

32.缓存的作用
减少网络带宽消耗 降低服务器压力 减少网络延迟,加快页面打开速度

33.HTTP缓存机制
当一个用户发起一个静态资源请求的时候,浏览器会通过以下几个步骤来获取资源:
强制缓存阶段:现在本地查找该资源,如果有发现该资源,而且该资源还没有过期,就使用这一个资源,完全不会发送http请求到服务器;
协商缓存阶段:如果在本地缓存找到对应的资源,但是不知道该资源是否过期或者已经过期,则发一个http请求到服务器,然后服务器判断这个请求,如果请求的资源在服务器上没有改动过,则返回304,让浏览器使用本地找到的那个资源。
缓存失败阶段:当服务器发现请求的资源已经修改过,或者这是一个新的请求(在本来没有找到资源),服务器则返回该资源的数据,并且返回200,当然这个是值找到资源的情况下,如果服务器上没有这个资源,则返回404

强制缓存
强制缓存就是在缓存有效期内,浏览器直接从本地缓存中获取资源,不需要与服务器进行交互。如果缓存过期,浏览器才会向服务器发送请求‌。
强制缓存的情况主要有三种,如下:
不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求(跟第一次发起请求一致)。
存在该缓存结果和缓存标识,但该结果已失效,强制缓存失败,则使用协商缓存。
存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果

协商缓存
协商缓存就是强制缓存失效后,浏览器携带缓存标识想服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程
主要有以下两种情况:
协商缓存生效,返回304,即数据未更改可以继续使用。
协商缓存失效,返回200,数据已发生更改,并返回客户端新的数据。

34.MVC模型与MVVM模型的区别
MVC模型:
M:model 模型层(模型层接受改变状态最终发送给视图层展现)
V:view 视图层(传递用户交互的指令给控制层)
C:controller 控制层(控制层实现相应的逻辑代码后返回给模型层)
优点:
1. 高内聚低耦合
2. 重用性高
3. 可维护性高
4. 有利于软件优化
5. 部署快,生命周期成本低
缺点:
1. 增加系统结构和实现的复杂性
2. 视图对模型数据的低效率访问,未变化数据重复访问
3. 不适合小、中型应用程序
4. 没有明确的定义

MVVM模型
MVVM主要通过模型层的默认数据来在视图层中显示,在通过在视图层中修改数据来改变模型层中的数据,从而实现视图层中的变化 MVVM模式的优点: MVVM解决了MVC中大量的DOM操作使得页面渲染性能降低,加载速度变慢,用户体验差,以及当model层发生改变时,开发者需要主动更新页面的问题。

35.什么是洋葱模型
最直观的体现就是 DOM 事件的捕获和冒泡机制, 一个事件到达指定的元素之前先会经过上级的所有元素,触达后又会往上冒泡 先进后出

36. Typscript 有了解吗,能讲讲吗

ts就是js的的强类型版本 

ts的声明:
接口: 接口(Interfaces)用来定义对象的类型
枚举: 可以定义一些带名字的常量, 用于清晰地表达意图或创建一组有区别的用例
泛型定义: 在定义函数、接口或者类的时候,不预先指定具体的类型,而是在使用的时候再指定类型。提高可重用性
解构:从数组和对象中提取值,对变量进行赋值,这被称为解构 // let [a, b, c] = [1,2,3] => let a= 1 let b = 2

37.三次握手的详述(通俗版)
首先客户端发送连接请求报文,服务端接受连接后回复ACK报文,并为这次连接分配资源。 客户端接收到ACK报文后也向服务端发送ACK报文,并分配资源,这样TCP连接就建立了。

38. 四次挥手的详述(通俗版)
假设Client端发起中断连接请求,意思是说"我Client端没有数据要发给你了",但是如果服务端还有数据没有发送完成,服务端就会发送"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息", 这时候Client端就进入等待状态。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入等待状态,Server端收到ACK后断开连接,Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。 Ok,TCP连接就这样关闭了!

39.vue中如何解析模板
模板是什么
对于vue来说,模板本质就是一个字符串
vue中的模板是有逻辑的,是动态的,如v-if,v-for等
与html格式很想,但有很大区别;html是静态的,而vue模板是动态的

40.模板必须转换为JS代码?
因为模板有逻辑(v-if,v-for),必须用JS才能实现 转换为html渲染页面,必须用JS才能实现渲染
因此模板需要转换为一个JS函数(render函数),(render函数是指的渲染函数,并不一定就必须是render这个名字)
function render(){ with(this){ // this就是vm return _c( 'div', { attrs:{'id':'app'} }, [ _c('p',[_v(_s(price))]) ] ) } }
vm._c 是创建DOM标签的
vm._v 是创建文本节点的
vm_s 就是 toString,因为price是number类型的,先变为字符串再创建文本节点

模板最终转换成render函数,render函数是什么样子的?
render函数中有with的语法
render函数返回的是vnode vnode 其实就属于虚拟dom了  

39. Loader和Plugin 有什么区别
Loader:直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到`loader`。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。 

Plugin:直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

40. 从输入一个url到浏览器页面展示都经历了哪些过程?
1、首先,在浏览器地址栏中输入url
2、浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。
3、在发送http请求前,需要域名解析(DNS解析),解析获取相应的IP地址。
4、浏览器向服务器发起tcp连接,与浏览器建立tcp三次握手。
5、握手成功后,浏览器向服务器发送http请求,请求数据包。
6、服务器处理收到的请求,将数据返回至浏览器
7、浏览器收到HTTP响应
8、读取页面内容,浏览器渲染,解析html源码
9、生成Dom树、解析css样式、js交互
10、客户端和服务器交互
11、ajax查询

41. HTTP协议由哪些部分组成HTTP

请求的组成状态行、请求头、消息主体三部分组成。HTTP 响应的组成状态行、响应头、响应正文。

42. **怎么加快首屏的加载
**1.对代码进行压缩,我们可以减小代码的体积量
2.路由懒加载
3.采用CDN引入,并在webpack配置。打包之后webpack进会从外部打包第三方引入的库,减小app.js的体积,从而提高首屏加载速度
4.ssr服务器渲染
5.增加宽带
6.对代码进行优化,加快加载和渲染的速度

43. **webpack的核心是什么
**四个核心 entry入口 output出口 plugins插件 loader加载器
插件: ProvidePlugin: 自动加载模块。
html-webpack-plugin: 生成HTML文件
clean-webpack-plugin: 用于在打包前清理上一次项目生成的 bundle 文件
copy-webpack-plugin: 拷贝静态资源到项目的dist文件夹下

44. call、apply、bind三者的用法和区别
call、apply、bind都是改变this指向的方法
fn.apply(this, [a,b])
fn.call(this, a, b)
fn.bind(this, a, b)   和call一模一样,区别在于立即执行还是等待执行

45.说一下怎么把类数组转换为数组

类数组:比如函数里的 argument
类数组是一个普通对象,而真实的数组是Array类型,但是不具有array的方法
转换方式: 通过call调用数组的slice方法来实现转换 Array.prototype.slice.call(arrayLike) 通过Array.from方法来实现转换 Array.from(arrayLike)

46. 说一下前端登录的流程?

初次登录的时候,前端调后调的登录接口,发送用户名和密码,后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token,和一个用户信息的值,前端拿到token,将token储存到Vuex中,然后从Vuex中把token的值存入浏览器Cookies中。把用户信息存到Vuex然后再存储到LocalStroage中,然后跳转到下一个页面,根据后端接口的要求,只要不登录就不能访问的页面需要在前端每次跳转页面师判断Cookies中是否有token,没有就跳转到登录页,有就跳转到相应的页面,我们应该再每次发送post/get请求的时候应该加入token,常用方法再项目utils/service.js中添加全局拦截器,将token的值放入请求头中 后端判断请求头中有无token,有token,就拿到token并验证token是否过期,在这里过期会返回无效的token然后有个跳回登录页面重新登录并且清除本地用户的信息

文章只是作为一个知识点的记录
入门前端人员,如果理论有错,欢迎各位大佬纠正
如果是描述不够详细,那是因为我还理解不到那么深奥的地方(理直气壮)