2021年前端面试题汇总(2021前端面试最新笔试题),本文通过数据整理汇集了2021年前端面试题汇总(2021前端面试最新笔试题)相关信息,下面一起看看。
【点击打开视频讲解面试技巧面试全过程】(【全网最全面试技巧】面试技巧和面试全过程_ 177777777语义学的主要目的可以概括为用正确的标签做正确的事情。HTMl语义可以结构化页面的内容,方便浏览器解析和
【点击打开视频讲解面试技巧全过程】(【全网最全面试问题】面试技巧及面试全过程_
哔哩哔哩)
一. HTML
1.语义话语的目的是什么?
语义学的主要目的可以概括为用正确的标签做正确的事情。
语义HTMl可以使页面的内容结构化,便于浏览器分析和搜索引擎分析。
提高了代码的可读性,
2.HTML5中的新元素
画布绘图和SVG绘图。
拖放)API
语义标签(标题、导航、页脚、文章、章节)
音频和视频(音频、视频)API
地理定位(地理位置)
LocalStorage,关闭浏览器后可以长时间存储数据而不丢失。
SessionStorage:浏览器关闭后数据会自动删除。
控件(日历、日期、时间、电子邮件、url、搜索)
3.cookie和会话存储与本地存储的区别
保存模式
Cookie存储在客户的浏览器中。
会话保存在客户端,不参与服务器通信。
生命周期
Cookie可以设置过期时间。
除非手动清除,否则LocalStorage将永久保存。
关闭当前页面或浏览器后,SessionStorage失败。
存储容量
大约4 KB cookie
会议5M
可用性
Cookie需要自己封装
会话可以接受本机接口。
因为每次http请求中都携带cookie,所以主要用于识别用户登录,可以使用localStorage
为了跨页面传输参数,可以使用sessionStorage来保留一些临时数据。
[点击打开视频详细讲解](
【面试问题】cookie、sessionStorage、localStorage的详细解释和区别__哔哩哔哩
)
[点击打开文章了解详情](
cookie、sessionStorage和localStorage的详细解释和区别_前端-早晚博客-CSDN博客_cookie、sessionstorage和localstorage
)
第二,CSS
1.CSS的基本选择器是什么,执行的顺序是什么?
选择器=#myId {}
类选择器=。我的班级{}
选择器=p,h1 {}
后代选择器=div h1 {}
子选择器=divh1 {}
兄弟选择器(所有兄弟)=ul~h1 {}
相邻同级选择器=ul h1 {}
Selector=li[name=\sss\] {}
类选择器=h1:hover {}
伪元素选择器=h1:before{}
通配符选择器*=* {}
!重要的内联样式(非选择器)ID选择器类选择器标签选择器通配符选择器(*)
2.纵向和横向对中方法有哪些?
[CSS中几种最常用的水平和垂直居中方法](
CSS中几种最常用的水平和垂直居中方法
)
3.常见的布局方法有哪些?什么是盒子模型?
[点击打开视频了解详情](
常见前端布局方法大全——详解__哔哩哔哩
)
[点击打开文章了解详情](
常用前端布局方法大全-详解_前端-晨末博客-CSDN博客
)
4.常用的块元素和行内元素有哪些?有什么特点?
元素:div,h1~h6,ul,li,table,p,br,form。
特点:独占一行,新行显示,宽度和高度可设置,块和行可嵌套。
行中的元素:span,a,img,textarea,select,option,input。
特点:只能在行内显示,内容可以在宽度和高度上展开,但宽度和高度不能设置(img、input、textarea等除外。).
5.清晰浮动
父div定义overflow:hidden(如果父元素在父元素之外有定位元素,超出的部分将被隐藏。)
向浮动元素的父元素添加标签(不推荐,因为添加标签会导致不必要的渲染)
伪元素清除浮动:添加。clearfix: after(内容:)到浮动元素父级;显示:表格;
明确:两者都有;)(不会添加新标签,也不会有其他影响。)
6.CSS3的新特性
圆角(边界半径)
箱形阴影
文本阴影效果(文本阴影)
线性梯度
转换(Transform)
CSS选择器
设置(背景)
颜色模式(rgba)
伪元素(:选择)
媒体查询(媒体)
多栏布局
图片(边框图像)
7.CSS中的长度单位是什么?
绝对长度单位:px
百分比:%
相对父元素字体大小单位:em
相对于根元素字体大小的单位:rem
相对于视窗宽度的百分比* (100vw是窗口宽度的100vw
相对于视窗*高度的百分比(100vh是窗口高度的100vh
8.px,em和rem的区别
[点击打开文章了解详情](
px,em,rem的区别_前端-黎明A的博客-CSDN博客_ PX是什么单位?
)
9.“显示:无”和“可见性:隐藏”之间的区别
Display:none:隐藏一个元素,该元素在文档布局中没有分配空间(从文档中移除),将导致重排。
可见性:隐藏:隐藏元素,但保留文档布局中的原始空间(仍在文档中),
不会造成回流(重绘)。
10.用CSS实现三角形。
【点击打开视频讲解】(
【面试问题】知道如何用纯css实现三角形吗?_哔哔哔哔哔哔哔哔哔哔哔
)
[点击打开文章解释](
【面试问题】知道如何用纯css实现三角形吗?_前端-晨曦博客A -CSDN博客
)
1、伪类和伪元素的区别
[点击打开文章解释](
css中伪类和伪元素的区别_前端-博客在晨间-博客在CSDN _ CSS中伪类和伪元素的区别
)
12.什么是重绘和重排?怎么解决?
重画/重画
一个dom节点的颜色,背景颜色变化,字体大小只影响自身,不影响其他元素。
注意:表及其内部元素可能需要多次计算来确定其在呈现树中的节点的属性,这需要两倍于等效元素的时间。这也是我们尽量避免使用表格来布局页面的原因之一。
重排(回流/回流/重构)
一个dom节点的宽度、高度、布局、隐藏发生变化,不仅自身发生变化,还会影响到其他元素。每页至少重排一次,即第一次加载页面时。
触发重排的原因
初始化页面呈现(不可避免)
或者添加或删除可见的DOM元素。
改变元素大小-尺寸,外缘距离;设计
浏览器窗口大小的变化
填充内容的更改(如文本或图像大小的更改)会导致计算值的宽度和高度发生变化。
读取一些元素属性:(offsetleft/top/height/width,clienttop/left/width/height,
scrollTop/Left/Width/Height,Width/Height,getComputedStyle(),
当前样式(IE))
1.重画不一定重排,重排一定会重画。
2.重绘和重排的成本很高,所以要尽量减少dom的增删。
如何解决
不是直接操纵样式,而是先设置类,再修改DOM的类名;
Position:absolute和flex不会导致重排。
不要把DOM节点的属性放在循环中作为循环变量;
从文档流中分离出所需的动画元素;
如果没有表格布局,
尽量不要修改影响大的DOM
如果要多次添加DOM,首先用document . createdocumentfragment()创建一个框,
盒子做好之后,先添加子元素,在插入的元素中添加;
13.过渡的过度属性有哪些?
[点击打开视频详细讲解](
【面试问题】CSS过渡属性综合讲解__哔哩哔哩
)
[点击打开文章了解详情](
【面试问题】CSS过渡属性综合讲解
)
14.链接和导入有什么区别?
Link是html标签,import是css提供的。
页面加载时,link会同时加载,而import引用的css会等到页面加载后再加载。
兼容性问题:只有IE5以上才能识别import,而link是html标签,所以不存在兼容性问题。
权重问题:进口权重高于链接权重。
DOM操作:DOM可以操作link中的样式,但不能操作import中的样式。
!- html文件-!-链接模式,推荐-linkrel=\ style sheet \ type=\ text/CSS \ href=\ style . CSS \ media=\ screen \ /!-import mode-style type=\ text/CSS \ media=\ screen \ 导入URL(style . CSS);/风格
15.常用的动画库有哪些?
[点击打开视频详细讲解](
八个可以解决你80%需求的CSS动画库__哔哩哔哩
)
[点击打开文章了解详情](
八个可以解决你80%需求的CSS动画库_前端-晨曦的博客A -CSDN博客
)
16.什么是BFC?
[点击打开视频详细讲解](
【面试问题】CSS中的BFC是什么?_哔哔哔哔哔哔哔哔哔哔哔
)
[点击打开文章解释](
【面试问题】CSS中的BFC是什么?_前端-晨曦博客A -CSDN博客
)
17.href和src的区别
[点击打开文章解释](
css-href和src的区别
)
18.如何让CSS只在当前组件中工作?
将当前组件的样式更改为样式范围。
第三,JS
1.什么是终结?
[点击打开视频详细讲解](
【面试问题】一个视频带你了解js封闭原理_剷剷剷剷剷剷剷剷剷剷剷剷剷剷剷剷剷211111111
)
[点击打开文章了解详情](
吃透js closure _前端-末端-晨晨博客-CSDN博客
)
2、调用、应用、绑定功能和区别(改变这一点)
[点击打开文章了解详情](
调用、应用和绑定的作用和区别
)
3.原型和原型链
[点击打开视频详细讲解](
【面试问题】javascript _ Billibili _ Billibili中的原型和原型链
)
[点击打开文章了解详情](
javascript中的原型和原型链_前端-末端-晨晨博客-CSDN博客
)
4.JS的基本数据类型
[点击打开视频详细讲解](
【面试问题】js基础数据类型和参考数据类型的区别和原理__哔哩哔哩
)
[点击打开文章了解详情](
javascript中的原型和原型链_前端-末端-晨晨博客-CSDN博客
)
5.导出和导出默认值之间的区别
[点击打开文章了解详情](
导出和导出默认值的区别和用途
)
6.箭头函数与普通函数的区别
-语法更简洁明了,=()
arrow函数是匿名函数,不能用作构造函数。不能使用new。
arrow函数不能用实参,用reat形参求解…
arrow函数没有自己的this,它会捕获其上下文的this值,并且其this不能被call()和apply()改变。
-Arrow函数没有原型。
7.GET和POST的区别
[点击打开文章了解详情](
get和post的区别_ Front-End-Morning A Blog-CSDN博客
)
8.forEach和map的区别
[点击打开视频详细讲解](
【面试问题】有什么用和区别。forEach()和。map()?_哔哔哔哔哔哔哔哔哔哔哔
)
[点击打开文章了解详情](
【面试问题】有什么用和区别。forEach()和。map()?
)
9.对象的继承
常见:
原型链继承
借用构造函数继承
原型借用构造函数的组合继承(使用call或applay方法)
ES6中类的继承(类可以由extends关键字继承)
10.简述你对面向对象的理解。
面向对象基于这样一种哲学观点,即一切都是对象。把一个对象抽象成一个类,就是把一个对象的静态和动态特征抽象成属性和方法,也就是把一类事物的算法和数据结构封装在一个类中,程序是由多个对象及其相互之间的通信组成的。
面向对象的特点是封装性、继承性和多态性。
封装:隐藏对象内部不需要暴露的细节,使内部细节的变化与外界隔离,只依靠接口进行交流。封装降低了编程的复杂性。
继承:它使得创建一个新类变得很容易,而一个类从派生类中获取其非私有方法和公共属性的繁琐工作就交给了编译器。
多态性:通过继承和实现接口和运行时类型绑定机制生成的多态性,使得不同类生成的对象对同一条消息做出不同的反应,大大提高了代码的通用性。
1.==和==的区别
[点击打开文章了解详情](
js==and===Difference _ Front-End-End晨晨一博-CSDN博客
)
12.数组的方法有哪些?
[点击打开文章了解详情](
js数组常用方法_前端-晨晨晨博客-CSD
-创建一个临时对象并将其指向该临时对象。
-将构造函数的原型属性和方法挂载到新对象的__proto__(原型指针)上。
-返回临时对象
15.JS获取HTML DOM元素的方法
-按ID获取(getElementById)
-通过名称属性(getElementsByName)
-通过标记名(getElementsByTagName)
-通过类名(getElementsByClassName)
-获取html (document.documentElement)的方法
-获取正文的方法(document.body)
-通过选择器(querySelector)获取元素
-通过选择器获取一组元素(querySelectorAll)
16.事件捕获和事件冒泡
-事件捕获和事件冒泡主要解决页面事件流的问题。页面的事件流经历了三个阶段,即事件捕获阶段、目标阶段和事件冒泡阶段。
-事件捕获是从外到内的;事件气泡是由内而外的。
-event.stopPropagation()可以阻止事件流的进一步传播。
-使用事件代理方法可以节省内存消耗,对于动态改变子元素也非常有利,避免了很多麻烦的步骤,比如重新绑定事件。(将子元素的事件委托给父元素)
17.虚拟dom
定义:虚拟DOM是一个普通的js对象。用于描述真实dom结构的Js对象被称为虚拟dom,因为它不是真实的dom。
功能:虚拟dom可以很好的跟踪当前的dom状态,因为它会根据当前的数据生成一个描述当前dom结构的虚拟dom。然后,当数据发生变化时,会生成一个新的虚拟dom,两个虚拟DOM只是保持变化前后的状态。然后,通过diff算法,计算当前两个虚拟dom的差值,得到较好的替换方案。
8.分类方法
冒泡排序:比较所有相邻的元素,如果第一个比第二个大就交换。
排序:找到数组中的最小值,选中后放在第一位。
插入排序:从第二个数字开始向前。如果比它大,就倒着走。
Merge:将数组一分为二,然后递归地“分割”数组,直到它被分割成单个的数字。
快速排序:从数组中选择任意一个基准,小于基准的元素全部放在基准前面,大于基准的元素放在前面。
基准背后。
9.数组操作方法会改变原来的数组。
会变化:push()、pop()、shift()、unshift()、splice()、sort()、reverse()。
未更改:concat(),split(),slice()。
js中substr()、substring()、splice()、split()和split()的区别和作用
[点击打开文章了解详情](
js _ Front-end-Late Morning Blog-CSDN博客中substr()、substring()、slice()、split()的区别和作用
)
20.JS判断变量类型的方法有几种?
Type:判断基本数据类型,对于除function以外的引用数据类型,返回‘function’。
返回“对象”。
实例:区分引用数据的类型。检测方法是检测到的类型在当前实例的原型链上,被它检测到。
结果都为真,不适合检测简单的数据类型。检测过程很繁琐,而且只针对简单的数据类型。
无法检测类型中未定义的空符号。
构造函数:检测引用数据类型。检测方法是获取实例的构造函数,判断是否与类相同。如果
同样意味着数据符合那个数据类型,这个方法不会在原型链中增加其他类。
进来避开原型链的干扰。
对象.原型. toString.call
():适用于各种判断测试。测试方法有
对象.原型. toString.call
(data)返回该数据类型的字符串。
(示例:字符串返回[对象字符串])
实例的实现原理:验证当前类的原型是否会出现在实例__proto__的原型链上,只要在其原型链上,结果为真。因此,instanceof将遍历左侧变量的原型链,直到找到右侧变量的原型,找到时返回true,没有找到时返回false。
Object.prototype.toString.call的原理:Object.prototype.toString表示返回对象类型的字符串,call()方法可以改变这个的方向,所以将Object.prototype.toString()方法指向不同的数据类型,返回不同的结果。
21.null和undefined有什么区别?
null和undefined的区别是:undefined是指一个变量已经声明但没有赋值,它是所有未赋值变量的默认值;Null表示变量将来可能指向某个对象,一般用于主动释放对该对象的引用。
(null和undefined有什么异同?
共同点:它们都是原语类型,本地存储在堆栈变量中。
差异:
(1)undefined——表示变量已声明,但尚未赋值。
它是所有未分配变量默认值。
比如:var a;//a被自动赋值为未定义。
(2)null——表示变量可能指向未来的对象。
通常用于主动释放对对象的引用。
2.什么时候使用null?
当您需要在使用一个更大的对象后释放它的内存时,设置为null。
3.定义
(1)未定义:是所有未赋值变量的默认值,会自动赋值。
(2)null:主动释放变量引用的对象,表示变量不再指向任何对象地址。
22.什么是跨域?和跨领域解决方案。
[点击打开视频详细讲解](
【面试问题】什么是跨域?以及七大跨域解决方案_ 1111111111111111111111;11
)
[点击打开文章了解详情](
【面试问题】什么是跨域?以及七大跨领域解决方案_前端-晨博-CSDN博客
)
23.防抖和节流的用途和区别
[点击打开视频详细讲解](
【面试问题】JavaScript防抖和节流的使用和区别__哔哩哔哩
)
[点击打开文章了解详情](
JavaScript防抖和节流的使用和区别_晨曦的前端-博客-晨曦的博客
)
24.堆栈内存和堆内存的区别和原理。
[点击打开视频详细讲解](
【面试问题】JS栈内存和堆内存的区别和原理__哔哩哔哩
)
[点击打开文章了解详情](
堆栈内存和堆内存的区别和原理_前端-晨晨晨晨的博客_ CSDN博客_堆栈内存和堆内存
)
25.深度复制和浅度复制的区别和原理
[点击打开视频详细讲解](
【面试问题】JS深抄和轻抄的区别和原理__哔哩哔哩
)
[点击打开文章了解详情](
深度复制和轻度复制的区别和原理_前端-上午晚些时候上午一个博客-CSDN博客
)
四。ES6的新功能
添加块级范围let定义变量和const定义常量。
变量的解构和赋值
模板( $ {} )
默认参数(键=值)
箭头(=)
扩展运算符(…)
模块(导入/导出)
类(类/扩展)
承诺
代理人
标志
[点击打开视频详细讲解](
【面试问题】var,let,const的使用和区别。什么是临时死区?_哔哔哔哔哔哔哔哔哔哔哔
)
[点击打开文章了解详情](
var,let,const的使用和区别,什么是临时死区?_前端-晨曦博客A -CSDN博客
)
承诺
意义:异步编程解决回调地狱的一种解决方案。
有三种状态:待定、已履行和已拒绝(承诺对象的状态变化只有两种可能:从待定到已履行和从待定到已拒绝)。)
resolved函数将Promise对象的状态从“未完成”更改为“成功”(即从待定更改为已解决)。
reject函数将Promise对象的状态从“未完成”更改为“失败”(即,从待定更改为已拒绝)。
生成Promise实例后,可以使用then方法分别指定resolved状态和rejected状态的回调函数。
Then: then: Promise实例在状态变化时增加一个回调函数。您可以接受两个回调函数作为参数。当Promise对象的状态变为resolved时调用第一个回调函数,当Promise对象的状态变为rejected时调用第二个回调函数。
缺点:承诺不能取消。一旦新创建,立即执行,不能中途取消。如果回调函数为否
动词(verb的缩写)计算机网络知识
1.HTTP和HTTPS
HTTP:客户机和服务器之间数据传输的格式规范,代表“超文本传输协议”。
HTTPS:在HTTP和TCP之间增加的安全协议层。
默认端口号:http: 80,HTTPS:443。
传输方式:http是明文传输,https是安全的ssl加密传输协议。
连接方式:http无状态;HTTPS协议由SSL HTTP协议构成,可用于加密传输和认证。
网络协议比http协议更安全。
2.TCP和UDP的区别
面向TCP连接(如先拨电话建立连接);UDP是无连接的,即发送数据前不需要建立连接。
TCP面向字节流,实际上TCP把数据看成一系列非结构化的字节流;UDP是面向消息的。
每个TCP连接只能是点对点的;UDP支持一对一、一对多、多对一和多对多的交互通信。
TCP报头开销为20字节;UDP的报头开销很小,只有8个字节。
TCP提供可靠的服务。UDP适用于一次只传输少量数据,可靠性要求不高的环境。
3.HTTP的常见状态代码
1开头的状态代码(信息类)
00,接受的请求正在被处理,信息状态码。
2开头的状态代码(成功类)
2xx(成功)表示成功处理请求的状态代码。
00(成功)服务器已成功处理请求。
3开头的状态代码(重定向)
3xx(重定向)表示需要进一步的操作来完成请求。通常这些状态代码用于重定向。
01,永久重定向,表示该资源已经被分配了一个新的URL。
02,临时重定向,表示该资源被临时分配了一个新的URL。
03,表示该资源有另一个URL。使用GET方法获取资源。
04,(未修改)自上次请求以来,所请求的网页未被修改。当服务器返回此响应时,将不会返回网页内容。
4开头的状态代码(客户端错误)
4xx(请求错误)这些状态码表示请求可能有错误,阻碍了服务器的处理。
400(错误的请求)服务器不理解请求的语法。
01表示发送的请求需要通过HTTP认证的认证信息。
03(禁止)服务器拒绝请求
44(未找到)服务器找不到请求的网页。
5开头的状态代码(服务器错误)
5xx(服务器错误)这些状态代码表示服务器在尝试处理请求时遇到了内部错误。这些错误可能是服务器造成的。
错误本身,而不是请求的错误。
00,(内部服务器错误)服务器遇到错误,无法完成请求。
03,表示服务器停机维护或过载,无法处理请求。
4.浏览器从输入网址到页面加载发生了什么?
1.在浏览器的地址栏中输入URL,然后按Enter。
2.浏览器查找当前URL中是否有缓存,并比较缓存是否过期。
3.DNS解析对应于URL的IP。
4.根据IP(三次握手)建立TCP连接。
5.HTTP发起一个请求。
6.服务器处理请求,浏览器接收HTTP响应。
7.呈现页面并构建DOM树。
8.关闭TCP连接(挥动四次)。
5.HTTP传输过程
含义:从连接建立到断开有七个步骤,即三波四波。
TCP连接建立
浏览器发送请求命令。
浏览器发送请求标题
服务器响应
服务器响应信息
服务器发送数据
断开TCP连接
6.浏览器如何渲染页面?
解析浏览器的html源代码,将HTML转换成dom树,
将CSS样式转换成样式表(CSS规则树),
浏览器会将CSS规则树附加到DOM树,并将它们组合起来生成一个渲染树。
生成布局(流),浏览器通过分析计算出每个渲染树节点的位置和大小,在屏幕上绘制出渲染树。
所有节点
绘制一个复合生成的页面。
7.性能优化
减少http请求的数量
减少DNS查找
避免重定向。
使用Ajax缓存
使用更少的全局变量,减少DOM操作的使用。
优化图片大小,通过CSS Sprites优化图片,
css放在上面,js放在下面。
8.webpack是怎么打包的,babel是什么?
Webpack:将所有依赖打包成bundle.js文件,按代码分成单元片段,按需加载。Webpack以public JS的形式编写脚本,但对AMD/CMD的支持也很全面,方便了老项目的代码迁移。
把这个项目作为一个整体。有了给定的主文件(比如index.js),Webpack会从这个文件中找到项目的所有依赖文件,用加载器进行处理,最后打包成一个(或多个)浏览器可识别的JavaScript文件。
Babel将es6、es7、es8等语法转换成浏览器可识别的es5或es3语法。
9.git和svn的区别
SVN是集中式版本控制系统,版本库集中在中央服务器中。首先,你必须从中央服务器获取最新版本。完成工作后,需要将工作推送到中央服务器。集中式版本控制系统必须联网才能工作(如果在局域网还可以,带宽够大,速度够快,如果在互联网上,网速慢的话我就纳闷了)
Git是一个分布式版本控制系统。没有中心服务器,每个人的电脑就是一个完整的版本库。这样工作的时候就不用联网了,因为版本都在自己的电脑上。我改了我电脑上的文件A,别人也改了我电脑上的文件A。这时候只要把自己的变化推给对方,就能看到对方的变化。
10、网络插座
WebSocket:允许服务器主动向客户端发送消息,适用于开发聊天室、多人游戏等协作应用。
WebSocket协议是一种基于TCP的新型网络协议。在WebSocket API中,浏览器和服务器只需要握手一次,就可以直接创建持久连接,进行双向数据传输。
1.要求和导入之间的差异
-通话时间
理论上,require runtime call可以在代码中的任何地方使用,甚至是在它被赋给一个变量之后。
Lmport是在编译时调用的,必须放在文件的开头,使用的格式也是确定的。
-遵循规范。
Require是AMD规范的引入方法。
导入es6是一个语法标准,如果兼容浏览器的话必须转换成es5语法。
-精华
要求是一个分配过程。事实上,require的结果是一个对象、数字、字符串、函数等。然后将require的结果赋给一个变量。
导入是一个解构的过程。
底层数据类型通过require引入时,属于复制这个变量。
当通过require引入复杂数据类型时,数据会生成对象的一个浅表副本。
当模块之间存在循环引用时,会输出已执行的模块,而不输出未执行的模块(比较复杂)。默认情况下,CommonJS模块导出一个对象,即使基础数据类型已导出。
ES6模块语法是JavaScript模块的标准编写方法,坚持用这种编写方法来代替Node.js的CommonJS语法
使用import代替require()。
//CommonJS写成const modulea=require(\ modulea \ );const func 1=modulea . func 1;const func 2=modulea . func 2;//ES6是从“modulea”导入{func1,func2}写入的;
使用导出而不是模块导出.
//commonJS写成var React=require(\ React \ );var bread crumbs=react . create class({ render(){ return nav/;}});module.exports=Breadcrumbs//ES6是从\react\ 导入React编写的;类面包屑扩展反应。component { render(){ return nav/;}};导出默认面包屑;
12、事件循环(Event Loop)
原因:JavaScript是单线程的,所有任务都需要排队,只有前一个任务完成后才会执行最后一个任务。
所有的任务都可以分为两种,一种是同步的,一种是异步的。
同步任务:主线程上排队等待执行的任务只有在前一个任务完成后才能执行;
异步任务:进入“任务队列”而不是主线程的任务。只有当\ 任务队列\ 通知主线程可以执行异步任务时,任务才会进入主线程执行。
同步任务和异步任务分别进入不同的执行环境。先执行同步任务,异步任务放入循环队列中挂起,同步任务完成后再执行队列中的异步任务。异步任务首先执行微观任务,然后执行宏观任务。如此循环往复。
微任务:Promise.then,catch,最后,async/await。
宏:整体代码脚本,UI渲染,setTimeout,setInterval,Dom事件,ajax事件。
宏观和微观任务是如何执行的?
执行顺序:先执行同步代码,遇到异步宏任务时将异步宏任务放入宏任务队列,遇到异步微任务时将异步微任务放入微任务队列。所有同步代码执行完毕后,异步微任务将从队列转移到主线程执行。微任务执行后,异步宏任务会从队列转移到主线程执行,循环往复,直到所有任务执行完毕。
13.什么是单页应用程序(SPA)
一个系统只加载一次资源,然后通过路由和ajax进行操作交互和数据交互,不刷新页面。
在一个页面上集成多个功能,甚至整个系统只有一个页面,所有的业务功能都是它的子模块,以特定的方式链接到主界面。
优势:
-前端和后端分离
-良好的交互体验3354用户不用刷新页面,页面显示流畅。
-减轻服务器压力。——服务器只输出数据。
-共享一组后端代码3354多个客户端可以共享一组后端代码。
-加载速度快,内容的改变不需要重新加载整个页面,对服务器的压力低。
缺点:
-SEO难。——数据渲染在前端完成。
-页面初始加载慢,页面复杂度提升很多。
多页面:一个应用有多个页面,页面跳转时刷新整个页面,每次请求一个新页面。
一点:SEO效果不错。
缺点:页面切换较慢,每次页面切换都需要选择性重载公共资源。
14.什么是优雅的退化和逐渐增强?
* *渐进式增强):** *首先为低版本浏览器构建页面,完成基本功能,然后为高级浏览器执行效果、交互和附加功能,以获得更好的体验。
* *优雅降级):** *一开始就构建网站的全部功能,然后针对浏览器进行测试和修复。
在传统的软件开发中,经常会提到向上兼容和向后兼容的概念。渐进增强相当于向上兼容,优雅退化相当于向后兼容。向后兼容是指高版本支持低版本,或者后来开发的版本支持并兼容早先开发的版本,但向上兼容很少。大部分软件都是向后兼容的。
两者的区别:
1.退化的优雅和逐渐增强只是同一事物的两种看法。
2.优雅退化的思想认为,网站应该为最先进、最完美的浏览器而设计。
3.渐进增强的观点是,要关注内容本身。
不及物动词VUE
1.对MVC和MVVM的理解
m:模型(数据模型),v:视图(视图),c:控制器(逻辑处理),VM:(连接模型和视图)
MVC:单向通信。它必须由控制器连接。
MVVM:数据的双向绑定,数据改变视图,视图改变数据。
2.数据双向绑定原理
答:通过数据劫持结合发布订阅模式,通过Object.defineProperty()为每个属性定义get和set
方法在数据更改时向订阅者发布消息,并触发相应的事件回调。
3.vue生命周期
Vue实例有一个完整的生命周期,即从开始创建、初始化数据、编译模板、挂载Dom渲染、更新渲染、卸载等一系列过程。我们称之为Vue的生命周期。一般来说,Vue实例从创建到销毁的过程就是生命周期。
-beforeCreate:在创建之前。此时组件实例刚刚创建,还没有进行数据观察和事件配置,所以无法获取数据。
-已创建:创建完成。vue实例已经完成了数据观察,属性和方法的计算(如props,methods,data,computed,watch此时可用),没有挂载到DOM上,所以el属性,el属性和ref属性的空数组是不可访问的。它通常用于简单的ajax请求和页面初始化。
-挂载前:挂载前。挂起前调用,第一次调用相关的render函数(虚拟DOM)。编译模板,从数据中的数据和模板生成html,完成el和数据的初始化。注意,还没有挂在html页面上。
-已安装:安装完成。也就是说,模板中的HTML被呈现到HTML页面中。此时可以通过DOM API获取DOM节点,访问$ref属性获取VNode信息和操作。ajax请求只会被执行一次。
-beforeUpdate:在数据更新之前调用,这发生在虚拟DOM重新呈现和修补之前,不会触发额外的重新呈现过程。
-更新:更新后。在由于数据更改而重新呈现和修补虚拟DOM后调用。
销毁前;毁灭之前。在实例销毁之前调用,并且实例仍然完全可用。(一般来说,一些重置操作是在这一步完成的,比如清除组件中的定时器和dom事件)
-销毁:销毁后。在实例被销毁后调用。调用之后,vue列指示的所有内容都将被解除绑定,并且所有事件侦听器都将被移除。
其他:
Activated:激活保活组件时调用。
停用:当保持活动组件被停用时调用。
4.为什么使用虚拟DOM(常见问题)
-创建real DOM的成本很高:real DOM node节点实现了很多属性,而vnode只实现了一些必要的属性。与此相比,创建一个vnode的成本相对较低。
-触发多个浏览器重绘和重流:使用vnode相当于增加了一个缓冲区,这样一个数据变化引起的所有节点变化都可以先在vnode中修改,然后对diff后所有有差异的节点一次性修改DOM树,以减少浏览器重绘和重流。
-虚拟dom本来就是一个js对象,所以具有跨平台的能力,可以在不同的平台上精确显示。
-虚拟DOM的性能好处不是最重要的,更重要的是,它让Vue具备了现代框架应该具备的高级特性。
5.v-if和v-show的功能和区别
不管v-show的值是真还是假,元素都会存在于html页面中;并且v的值-如果为真,元素将
存在于html页面中。
v-show指令是通过修改元素的显示属性来实现的。
V-if动态地在DOM树中添加或删除DOM元素,v-show通过设置DOM元素的显示样式属性来控制。
隐形的。
V-if是“真”条件呈现,因为它将确保快速条件中的事件侦听器和子组件被正确销毁
重建。
V-if也是惰性的。如果在初始渲染时条件为假,则什么都不会做,并且直到条件第一次变为真,渲染才会开始。
条件块。
V-show不管初始条件是什么,元素总是会基于css进行反向渲染和简单切换。
一般来说,v-if的切换开销较高,而v-show的初始渲染开销较高。
所以如果需要非常频繁的切换,最好用v-show,如果运行时条件不会改变,最好用v-if。
在以下情况下切换生命周期功能的执行
控制显示
初始渲染
当初始值为false时,它将不会被渲染(即所谓的lazy ),也不会执行生命周期函数。
当初始值为真时,组件开始渲染,生命周期为创建前、已创建、挂载前、已挂载等。被依次执行。
切换时
True to true:在创建之前执行,在创建之后执行,在装载之前执行,依次执行。
判断正误:先执行后销毁,依次销毁。
虚拟展示
初始渲染
不管初始状态是真还是假,组件都会被渲染,并且在创建之前,创建,挂载之前和挂载之后会被依次执行。
转变成
基于css的切换,改变生命周期
函数无影响.
5、用过vue的哪些组件?
1、vue-route
2、axios
3、vuex
4、Element UI
5、swiper
6、vue-echarts
7、vue-video-player
8、vue-photo-preview等等
6、vue-router 的模式有?
1、hash模式,用URL hash值来做路由,支持所有浏览器;该模式实现的路由,在通过链接后面
添加““#”+路由名字”。
2、history模式,由h5提供的history对象实现,依赖H5 History API和服务器配置。
3、abstract模式,支持所有JS运行环境,如Node服务器端,如果发现没有浏览器的API,路由会
自动强制进入该模式。
7、组件之间如何传值
Vue父子 组件之间传值
子组件通过props来接受数据和通过$emit来触发父组件的自定义事件
兄弟组件之间的传值
建一个公共组件bus.js.。传递方通过事件触发bus.$emit。接收方通过在mounted(){}生命周期
里触发bus.$on。
可以通过VUEX 来跨组件传参
父孙传值 `$attrs`(向下)`$listeners`(向上)
祖先和子孙传值provide/inject
获取父组件实例this.$parent
8、路由之间如何传参
- 通过router-link路由导航跳转传递
<router-link to=`/a/${id}`>routerlink传参</router-link>
- 跳转时使用push方法拼接携带参数。
this.$router.push({ path: `/getlist/${id}`, })
- 通过路由属性中的name来确定匹配的路由,通过params来传递参数
this.$router.push({ name: \Getlist\, params: { id: id } })
- 使用path来匹配路由,然后通过query来传递参数。
this.$router.push({ path: \/getlist\, query: { id: id }})
注意:query有点像ajax中的get请求,而params像post请求。
params在地址栏中不显示参数,刷新页面,参数丢失,
其余方法在地址栏中显示传递的参数,刷新页面,参数不丢失。
9、VUEX
原理:Vuex是专门为vue.js应用程序设计的状态管理工具。
1、state 保存vuex中的数据源,通过this.$store.state获取
2、getters用于监听state中的值的变化,返回计算后的结果。getter的返回值会根据它的依赖
被缓存起来
3、mutations 是修改store中的值得唯一方式
//this.$store.commit
(\add\)
4、action 官方建议提交一个actions,在actions中提交mutations再去修改状态值。
this.$store.dispatch(\add\)
5、modules 模块化
10、如何解决vuex页面刷新数据丢失问题?
原因:因为vuex里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,vuex里面的数据就会被清空。
解决方法:将vuex中的数据直接保存到浏览器缓存中。(一般是用sessionStorage)
11、computed和watch的区别?
computed值有缓存、触发条件是依赖值发生更改、 watch无缓存支持异步、监听数据变化
computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生
改变,下一次获取 computed 的值时才会重新计算 computed 的值;
watch: 的是观察的作用,支持异步,类似于某些数据的监听回调 ,每当监听的数据变化时都
会执行回调进行后续操作;
computed应用场景:需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以
利用 computed 的缓存特性,避免每次获取值时,都要重新计算;
watch应用场景:需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch
选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结
果前,设置中间状态。这些都是计算属性无法做到的。
[点击打开视频讲解更加详细](
2022年最新版《Vue2入门到精通系列》全套教程 超十几万字文章总结及案例、非常详细_哔哩哔哩_bilibili
)
[点击打开文章详解](
《Vue2入门到精通系列》超十几万字文章总结及案例_前端--末晨曦吖的博客-CSDN博客_精通vue2
)
12、route和router的区别
- route:是路由信息对象,包括“path,parms,hash,name“等路由信息参数。
- router:是路由实例对象,包括了路由跳转方法,钩子函数等。
13、vue中数据变了但是视图不跟新怎么解决?
vue不能检测以下变动的数组:
1、当你利用索引直接设置一个项时,vm.items[indexOfItem] = newValue
2、当你修改数组的长度时,例如: vm.items.length = newLength
对象属性的添加或删除
由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
解决办法:
使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上
Vue.set(vm.someObject, ‘b’, 2) 或者 this.$set(this.someObject,‘b’,2) (这也是全局 Vue.set 方法的别名)
异步更新队列
在最新的项目中遇到了这种情况,数据第一次获取到了,也渲染了,但是第二次之后数据只有在再一次渲染页面的时候更新,并不能实时更新。
Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。
解决办法:
可在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数在 DOM 更新完成后就会调用
[点击打开视频讲解更加详细](
【面试题】Vue的this.$nextTick方法,异步更新dom详解_哔哩哔哩_bilibili
)
[点击打开文章详解](
【面试题】Vue的this.$nextTick方法,异步更新dom详解_前端--末晨曦吖的博客-CSDN博客
)
14、vue中data为什么是函数而不是对象?
vue组件是可复用的vue实例,一个组件被创建好之后,就可能被用在各个地方,而组件不管被复用了多少次,组件中的data数据都应该是相互隔离,互不影响的.
基于这一理念,组件每复用一次,data数据就会被复制一次,之后,当某一处复用的地方组件内data数据被改变时,其他复用地方组件的data数据不受影响。
如果data是对象的话,每当被复用是,复用的对象和源对象都会指向同一个内存地址(浅拷贝),互相之间相互影响,所以要是函数
15、vue中父子组件传值,父组件异步请求,子组件不能实时更新怎么解决?(vue中数据不能实时更新怎么解决?)
首先了解父子组件生命周期执行顺序
加载渲染数据过程
父组件 beforeCreate
父组件 created
父组件 beforeMount
子组件 beforeCreate
子组件 created
子组件 beforeMount
子组件 mounted
父组件 mounted
原因:因为生命周期只会执行一次,数据是要等到异步请求以后才能拿到,那么子组件的mounted钩子执行的时候,还没有拿到父组件传递过来的数据,但是又必须要打印出来结果,那这样的话,就只能去打印props中的默认值空字符串了,所以打印的结果是一个空字符串。
解决办法:
1、使用v-if控制组件渲染的时机
初始还没拿到后端接口的异步数据的时候,不让组件渲染,等拿到的时候再去渲染组件。使用v-if=\"变量\"去控制,初始让这个变量为false,这样的话,子组件就不会去渲染,等拿到数据的时候,再让这个变量变成true,
举例:
data() { return { isTrue:false // 初始为false }; }, monted(){ this.$post.a.b.c.getData(res=>{ if(res.result){ this.isTrue = true } }) }
2、使用watch监听数据的变化
举例:
props: { tableData: { type: Array, default: [], }, }, watch: { tableData(val){ console.log(val) } },
3、使用VueX
Vue 路由跳转方式
router-link 标签跳转
this.$router.push()
this.$router.replace()
this.$router.go(n):(0:当前页,-1上一页,+1下一页,n代表整数)
17、Vue 中 for循环为什么加 key?
为了性能优化, 因为vue是虚拟DOM,更新DOM时用diff算法对节点进行一一比对,比如有很多li元素,要在某个位置插入一个li元素,但没有给li上加key,那么在进行运算的时候,就会将所有li元素重新渲染一遍,但是如果有key,那么它就会按照key一一比对li元素,只需要创建新的li元素,插入即可,不需要对其他元素进行修改和重新渲染。
key也不能是li元素的index,因为假设我们给数组前插入一个新元素,它的下标是0,那么和原来的第一个元素重复了,整个数组的key都发生了改变,这样就跟没有key的情况一样了。
18、vue路由守卫有哪些?
路由守卫分为三种 ——分别是:全局路由守卫、组件路由守卫、独享路由守卫。
全局守卫
全局守卫又分为全局前置守卫、和后置守卫
1. router.beforeEach((to,from,next)=>{})
回调函数中的参数,to:进入到哪个路由去,from:从哪个路由离开,next:函数,决定是否展示你要看到的路由页面。
从名字全局前置守卫不难理解,它是全局的,即对 整个单页应用(SPA) 中的所有路由都生效,所以当定义了全局的前置守卫,在进入每一个路由之前都会调用这个回调,那么如果你在回调中对路由的跳转条件判断出错,简单点就是死循环…因为你遗漏了某种路由跳转的情况,守卫会一直执行。所以在使用全局前置守卫的时候一定要判断清楚可能会出现的路由跳转的情况。
2.router.afterEach((to, from) => {})
只有两个参数,to:进入到哪个路由去,from:从哪个路由离。
理解了全局前置守卫,那么全局后置守卫也就那么一回事。全局后置守卫是整个单页应用中每一次路由跳转后都会执行其中的回调。所以多用于路由跳转后的相应页面操作,并不像全局前置守卫那样会在回调中进行页面的重定向或跳转。
组件内的守卫
组件路由守卫分为到达这个组件时,离开这个组件时
1. beforeRouteEnter:(to,from,next)=>{}——到达
to,from参数与上面使用方法一致。next回调函数略有不同。
2.beforeRouteUpdate:(to,from,next)=>{}——更新
3. beforeRouteLeave:(to,from,next)=>{}——离开
点击其他组件时,判断是否确认离开。确认执行next();取消执行next(false),留在当前页面。
路由独享的守卫
1. beforeEnter:(to,from,next)=>{}
与全局路由守卫用法一致,但是只能针对一个页面使用
19、vue常的修饰符
.stop:等统JavaScript中的event.stopPropagation(),防事件冒泡
.prevent:等同于JavaScript中的event。preventDefault(),防执预设的为(如果事件可
取消,则取消该事件,不停事件的进步传播);
.capture:与事件冒泡的向相反,事件捕获由外到内
.self:只会触发范围内的事件,不包含元素;
.once:只会触发次。
20、vue的两个核点
数据驱动:ViewModel,保证数据和视图的致性
组件系统:应类UI可以看做全部是由组件树构成的
21、delete和Vue.delete删除数组的区别
delete只是被删除的元素变成了empty/undefined其他的元素的键值还是不变。
Vue.delete直接删除了数组 改变了数组的键值
22、vue常的UI组件库
Mint UI,element,VUX
23、Vue首页白屏是什么问题引起的?如何解决呢?
[点击打开视频讲解更加详细](
【面试题】Vue首页白屏是什么问题引起的?如何解决呢?_哔哩哔哩_bilibili
)
[点击打开文章详解](
Vue首页白屏是什么问题引起的?如何解决呢?_前端--末晨曦吖的博客-CSDN博客_vue首页空白
)
24、性能优化篇
[点击打开文章详解](
前端面试必问及加分点---性能优化篇_前端--末晨曦吖的博客-CSDN博客_前端性能优化面试题
)
七、React
1、react的生命周期
生命周期是什么?
react 实例的生命周期,就是react实例从初始化,更新,到销毁的过程
react实例生命周期经历三个阶段
初始化阶段:完成从react组件创建到首次渲染的过程
更新阶段:当调用setState函数时,会引起组件的重新渲染
销毁阶段:完成组件的销毁
三个阶段分别对应的构造函数有
初始化阶段:
constructor
构造函数里,可以做状态的初始化,接收props的传值
componentWillMount: 在渲染前调用,相当于vue中的beforeMount
render
渲染函数,不要在这里修改数据。 vue中也有render函数。
componentDidMount
渲染完毕,在第一次渲染后调用。
运行中阶段(更新)
当组件的 props 或 state 发生变化时会触发更新(严谨的说,是只要调用了setState()或者改变了props时)。组件更新的生命周期调用顺序如下:
shouldComponentUpdate
是否更新? 需要返回true或者false。如果是false,那么组件就不会继续更新了。
componentWillUpdate
即将更新。
componentWillReceiveProps(nextProps): 在组件接收到一个新的 prop (更新后)时被调用。
这个方法在初始化render时不会被调用。nextProps 是props的新值,而 this.props是旧值。
render
不要在这里修改数据
componentDidUpdate
在组件完成更新后立即调用。在初始化时不会被调用。 相当于vue中的updated
销毁阶段(卸载)
componentWillUnmount()
即将卸载,可以做一些组件相关的清理工作,例如取消计时器、网络请求等
2、为什么虚拟DOM 会提高性能
首先,(虚拟DOM是什么) 虚拟DOM就是一个JavaScript对象。通过这个JavaScript对象来描述真实DOM
如:
{ tagName:\"p\", style:\"width:200px;height: 100px;\", innerHTML:\"我是p\"},
其次,操作虚拟DOM,就是在操作javascript对象,所以,并不会引起页面的重绘和重排。而操作真实DOM是会引起页面的重绘和重排的。
3、React的diff原理
传统diff算法
需要遍历整棵树的节点然后进行比较,是一个深度递归的过程,运算复杂度常常是O(n^3)
react diff的优化策略
DOM节点跨层级的操作不做优化,因为很少这么做,这是针对的tree层级的策略;
对于同一个类的组件,会生成相似的树形结构,对于不同类的组件,生成不同的树形结构,这是针对
conponent层级的策略;
对于同一级的子节点,拥有同层唯一的key值,来做删除、插入、移动的操作,这是针对element层级
的策略;
4、调用setState之。