请确保JS等基本功熟练后进行翻阅,文章篇幅过长可以进行理解但是不能硬背
CSS
- display:none; 和visibility:hidden;的区别是什么?
display:none 隐藏对应的元素,在文档布局中不再给它分配空间,它各边的元素会合拢,就当他从来不存在。
visibility:hidden 隐藏对应的元素,但是在文档布局中仍保留原来的空间。
- CSS 优先级和权重值如何计算?
内嵌样式>内部样式>外部样式>导入式
- 什么是CSS盒模型?
盒模型由:外边距margin、边框border、内边距padding、内容content四个部分组成 标准盒模型大小=border+padding+content // 怪异盒模型大小=content
- 如何水平垂直居中一个元素?
弹性盒子 / 定位
.box{
display: flex;
justify-content: center;
align-items: center;
} //弹性盒子
.box{
position: relative;
}
.box .sub{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/*margin-left: 负的宽度的一半*/
/*margin-top: 负的高度的一半*/
}//定位
- 请解释CSS中的相对定位(relative positioning)和绝对定位(absolute positioning)
答:相对定位和绝对定位都是CSS中的定位方法。 相对定位(position:
relative):元素按照正常文档流进行布局,然后根据给定的偏移值(top, right, bottom,
left)进行调整,不脱离文档流。 绝对定位(position:
absolute):元素相对于其包含块(离元素最近的一个定位祖先元素、未使用定位的块盒祖先元素或初始化包含块)进行布局,脱离文档流,不占据空间。
6.请简述CSS浮动(float)的概念
答:浮动是一种CSS布局技术,允许元素沿着其容器的左侧或右侧顺着文本和内联元素移动。常见的浮动值有float: left和float:
right。浮动会影响包含它的容器高度,因此可能需要使用clearfix技术来消除浮动影响
7.什么是Flexbox?
答:Flexbox(弹性盒模型)是一种CSS布局模型,旨在在不同屏幕尺寸和设备上实现更灵活的布局。Flexbox通过对父容器和子元素应用display:
flex属性来设置布局,使子元素能够自动调整大小以适应父容器的空间。使用Flexbox,我们可以轻松实现垂直和水平居中、重新排序和对齐等布局需求
8.什么是!important声明,如何使用它?
答:!important 声明用于提高某个CSS样式的优先级。在样式声明后添加 !important
标记,可以使该样式在特异性相同时优先级更高。例如:
bash p { color: red !important; }
但在实际开发中,避免过多依赖!important,应尽可能通过提高特异性来解决样式冲突问题。
9.请描述一个浏览器兼容性问题以及解决方法。
答:一个典型的浏览器兼容性问题是 CSS3 圆角边框(border-radius)属性在老旧版本的 Internet
Explorer(如IE8)中不被支持。为了解决这个问题,我们可以使用图片背景作为替代方案,或者利用 JavaScript库(如CSS3Pie)为老旧浏览器提供相应的支持。
10.请解释CSS伪类与伪元素的区别。
答:伪类(pseudo-class)主要用于描述某个元素的状态。如::hover、:active 和
:checked等。伪元素(pseudo-element)是用于创建网页中一些不存在于HTML文档树中的元素,例如::before 和:after。伪元素使用两个冒号表示,而伪类则使用一个冒号。
- 什么是BFC(Block Formatting Context),它的作用是什么?
答:BFC(Block Formatting
Context)是块级格式化上下文,是一个独立的布局环境,它影响内部元素的定位以及与其他元素的相互作用。清除浮动、外边距重叠和自适应布局都涉及BFC的规则。一个元素可以通过设置overflow属性为非visible、设置float属性为left或者right以及设置display属性为inline-block、table-cell等来创建BFC。
- 在CSS中,z-index的作用是什么?如何正确使用z-index?
答:在 CSS 中,z-index 用于控制元素的堆叠顺序。z-index 只对定位元素(position 属性值为
relative、absolute、fixed 或 sticky 的元素)有效。默认情况下,元素的 z-index 为
auto,可以设置一个整数值来调整堆叠顺序。值越高,元素将显示在越上面。在实际使用中,尽量避免使用过大的 z-index值,并根据实际需求合理设置堆叠顺序。
13 .为什么要使用CSS预处理器?请列举一些常用的CSS预处理器。
答:CSS预处理器具有一些高级功能,如变量、嵌套、运算和混入(Mixins),可以简化CSS编写、提高代码可维护性并减少代码冗余。常用的CSS预处理器包括Sass、Less
14 .如何实现CSS动画?
答:可以通过两种方法实现CSS动画:使用transition属性对元素的状态变化进行平滑过渡,或使用@keyframes规则定义关键帧动画。transition属性适用于简单的动画效果,而@keyframes允许创建更复杂的动画序列
14 .如何使用CSS选择器?
答:CSS选择器用于识别页面中要应用样式的元素。有多种类型的选择器,如:
元素选择器: 通过HTML元素名称选择元素,如p、h1等。
类选择器: 通过元素的class属性选择元素,以.开头,如.myClass。 ID选择器:
通过元素的ID属性选择元素,以#开头,如#myID。 后代选择器:选择某元素的所有后代元素,如ul li。
子元素选择器:选择某元素的直接子元素,如ul > li。 属性选择器: 通过元素属性选择元素,如input[type=“text”]。
伪类选择器: 通过元素的状态或关系选择元素,如a:hover、li:first-child。
伪元素选择器:选择文档元素的特定部分,如::before、::after。
15.什么是浏览器的渲染流程?
答:浏览器的渲染流程通常包括以下步骤: 解析HTML文档,创建DOM树;
解析CSS样式(包括内联、外部和计算样式),创建CSSOM(CSS对象模型); 将DOM树和CSSOM结合,生成渲染树(Render
Tree); 布局(Layout):计算渲染树上元素的位置和大小; 绘制(Painting):将元素显示到屏幕上;
回流(Reflow)与重绘(Repaint):当元素的位置、大小或样式发生改变时,浏览器需要重新渲染元素。回流涉及到布局更新,重绘仅涉及到元素的视觉更新。
优化浏览器渲染性能是提高网页加载速度和用户体验的关键部分。
16.常见的页面布局方式:双飞翼、多栏、弹性、流式、瀑布流、响应式布局 六种
(1)双飞翼:两边定宽,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染,在双飞翼布局中,左侧和右侧的边栏使用了浮动(float)属性,并通过负外边距(margin-left和margin-right)将其移出了正常的文档流。这样做是为了不影响中间内容区域的宽度。中间内容区域使用了自动外边距(margin-left:auto和margin-right:auto)来使其居中,并通过设置左右两个边栏的宽度来确定中间内容区域的实际宽度。
(2)多栏:用于在网页上实现多个列并排显示内容。它可以将页面分为多个列,并且每个列可以有不同的宽度和高度,在bootstrap和其他UI框架中都有其身影.
(3) 弹性布局(Flexbox): 屏幕和浏览器窗口大小发生改变也可以灵活调整布局;
可以指定伸缩项目沿着主轴或侧轴按比例分配额外空间(伸缩容器额外空间),从而调整伸缩项目的大小;
可以指定伸缩项目沿着主轴或侧轴将伸缩容器额外空间,分配到伸缩项目之前、之后或之间;
可以指定如何将垂直于元素布局轴的额外空间分布到该元素的周围;
(4)瀑布流:
瀑布流布局从上到下,逐列排列元素,每一列上的元素根据其高度动态调整位置,以保持整体布局的平衡性,瀑布流布局可以根据内容的高度自动调整位置,使页面呈现出错落有致、可以使用CSS和JavaScript来创建瀑布流布局。CSS方面,可以使用属性如column-count、column-gap和break-inside来设置列数、列之间的间隔和避免元素在中断列中换行。JavaScript方面,可以使用流行的库如Masonry或Isotope来实现瀑布流布局。
(5)流式布局:固定布局和流式布局在网页设计中最常用的两种布局方式。固定布局能呈现网页的原始设计效果,流式布局则不受窗口宽度影响,流式布局使用百分比宽度来限定布局元素,这样可以根据客户端分辨率的大小来进行合理的显示。
(6)响应式布局:面对不同分辨率设备灵活性强,能够快捷解决多设备显示适应问题但是兼容各种设备工作量大,效率低下,代码累赘,会出现隐藏无用的元素,加载时间加长
17.常用的css属性
css属性非常多想全部记住几乎不可能,但在面试中也会出现问一下有关有常用的css记忆部分即可
display: | |
---|---|
block | 将元素显示为块级元素,独占一行,默认情况下宽度会填充父容器 |
inline | 将元素显示为内联元素,不会独占一行,只占据自身内容所需的空间 |
inline-block | 将元素显示为内联块级元素,不会独占一行,但可以设置宽度和高度 |
none | 将元素隐藏,不占据空间,相当于元素不可见 |
flex | 将元素显示为弹性盒子容器,可以方便地进行灵活的布局 |
grid | 将元素显示为网格容器,可以进行复杂的网格布局 |
table、table-cell | 将元素显示为表格或表格单元格,可以实现表格布局的效果 |
inline-flex | 将元素显示为内联弹性盒子容器 |
inline-table | 将元素显示为内联表格 |
(2) position:
static | 元素的默认值,即没有定位,遵循正常的文档流对象 |
---|---|
fixed | 元素的位置相对于浏览器窗口是固定位置。即使窗口是滚动的它也不会移动 |
relative | 移动相对定位元素,但它原本所占的空间不会改变,相对定位元素的定位是相对其正常位置。 |
absolute | 绝对定位的元素的位置相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于 html :absolute 定位使元素的位置与文档流无关,因此不占据空间。absolute 定位的元素和其他元素重叠。 |
sticky | sticky 英文字面意思是粘,粘贴,所以可以把它称之为粘性定位。position: sticky; 基于用户的滚动位置来定位,注意: Internet Explorer, Edge 15 及更早 IE 版本不支持 sticky 定位。 |
z-index | z-index属性指定了一个元素的堆叠顺序(哪个元素应该放在前面,或后面) |
---|---|
float | left 元素向左浮动。right 元素向右浮动。none 默认值。元素不浮动,并会显示在其在文本中出现的位置。inherit 规定应该从父元素继承 float 属性的值。 |
text-align | left 把文本排列到左边。默认值:由浏览器决定。right 把文本排列到右边。center 把文本排列到中间。justify 实现两端对齐文本效果。inherit 规定应该从父元素继承 text-align 属性的值。 |
overflow | visible 默认值。内容不会被修剪,会呈现在元素框之外。hidden 内容会被修剪,并且其余内容是不可见的。scroll 内容会被修剪,但是浏览器会显示滚动条以便查看其余的内容。auto 如果内容被修剪,则浏览器会显示滚动条以便查看其余的内容。inherit 规定应该从父元素继承 overflow 属性的值。 |
transition | css3设置元素的过渡效果 |
transform | 设置元素的变换效果(如旋转、缩放、平移等) |
text-decoration | 设置文本的装饰效果,如下划线、删除线等 |
text-transform | 设置文本的大小写转换,如大写、小写、首字母大写等 |
text-shadow | 设置文本的阴影效果 |
line-height | 设置行高,控制行与行之间的间距 |
letter-spacing | 设置字符间的间距 |
word-spacing | 设置单词间的间距 |
vertical-align | 设置元素的垂直对齐方式 |
list-style | 设置列表项的样式,包括列表标记、列表项缩进等 |
opacity | 设置元素的透明度 |
box-shadow | 设置元素的阴影效果 |
text-shadow | 设置文本的阴影效果 |
cursor | 设置鼠标指针在元素上的样式 |
pointer-events | 设置元素是否接受鼠标事件 |
有关背景图片 | |
---|---|
background-repeat | repeat:默认值,背景图片在水平和垂直方向上进行平铺重复。repeat-x:背景图片在水平方向上进行平铺重复。repeat-y:背景图片在垂直方向上进行平铺重复。no-repeat:背景图片不进行重复,只在元素的一部分显示。 |
background-position | top left:背景图片位于元素的左上角。center center:背景图片水平和垂直方向上都居中。bottom right:背景图片位于元素的右下角。可以使用具体的像素值或百分比来精确指定位置。 |
background-attachment | 定义背景图片的滚动方式。常见取值有:scroll:背景图片会随着元素的滚动而滚动。fixed:背景图片在元素的位置固定,不随滚动而滚动 |
标签上 title 与 alt 属性的区别是什么? | alt 是给搜索引擎识别,在图像无法显示时的替代文本;title 是关于元素的注释信息,主要是给用户解读。当鼠标放到文字或是图片上时有 title 文字显示。(因为 IE 不标准)在 IE 浏览器中 alt 起到了 title 的作用,变成文字提示。在定义 img 对象时,将 alt 和 title 属性写全,可以保证在各种浏览器中都能正常使用。 |
18.href 与 src?
href (Hypertext
Reference)指定网络资源的位置,从而在当前元素或者当前文档和由当前属性定义的需要的锚点或资源之间定义一个链接或者关系。(目的不是为了引用资源,而是为了建立联系,让当前标签能够链接到目标地址。)
src source(缩写),指向外部资源的位置,指向的内容将会应用到文档中当前标签所在位置。 href与src的区别
请求资源类型不同:href 指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的联系。在请求 src
资源时会将其指向的资源下载并应用到文档中,比如 JavaScript 脚本,img 图片; 作用结果不同:href
用于在当前文档和引用资源之间确立联系;src 用于替换当前内容; 浏览器解析方式不同:当浏览器解析到src
,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等也如此,类似于将所指向资源应用到当前内容。这也是为什么建议把
js 脚本放在底部而不是头部的原因。
19.calc, support, media各自的含义及用法?
@support主要是用于检测浏览器是否支持CSS的某个属性,其实就是条件判断,如果支持某个属性,你可以写一套样式,如果不支持某个属性,你也可以提供另外一套样式作为替补。
calc() 函数用于动态计算长度值。 calc()函数支持 “+”, “-”, “*”, “/” 运算;
@media 媒体查询,你可以针对不同的媒体类型定义不同的样式。
20.1rem、1em、1vh、1px各自代表的含义?
rem是全部的长度都相对于根元素元素。通常做法是给html元素设置一个字体大小,然后其他元素的长度单位就为rem。
em子元素字体大小的em是相对于父元素字体大小
元素的width/height/padding/margin用em的话是相对于该元素的font-size
vw/vh 全称是
Viewport Width 和 Viewport Height,视窗的宽度和高度,相当于 屏幕宽度和高度的
1%,不过,处理宽度的时候%单位更合适,处理高度的 话 vh 单位更好。
px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。 一般电脑的分辨率有{19201024}等不同的分辨率
19201024 前者是屏幕宽度总共有1920个像素,后者则是高度为1024个像素
- HTML、XML、XHTML它们之间有什么区别?
HTML、XML 和 XHTML 都是用于创建网页和在线应用程序的标记语言。它们之间有一些关键区别:
- HTML(超文本标记语言):
HTML 是一种用于创建网页的标准标记语言。它使用一系列称为标签的元素来定义网页的结构和内容。HTML 是一种非常宽松的> 标记语言,它允许一定程度的错误和不规范的编码。
- XML(可扩展标记语言):
XML 是一种用于存储和传输数据的标记语言。它是一种更加严格和灵活的标记语言,允许用户自定义标签和属性。XML 的设计> 目标是简化数据共享和传输,因此它在许多 Web 服务和应用程序中得到了广泛应用。
- XHTML(可扩展超文本标记语言):
XHTML 是 HTML 和 XML 的结合体。它是一种将 HTML 转换为 XML 的语言,这意味着 XHTML 文档必须遵循 XML 的严格规则。> XHTML 的主要目标是提高 Web 文档的可访问性、可维护性和可处理性。XHTML 在浏览器中的显示方式与 HTML 相同,但它的> 编码和解析方式与 HTML 不同。总结一下,HTML、XML 和 XHTML 之间的主要区别在于它们的严格性和灵活性。HTML 是一种非常宽松的标记语言,而 XML > 和 XHTML 则更加严格和灵活。XML 主要用于数据存储和传输,而 XHTML 则是将 HTML 转换为 XML 的语言。
21网站TDK三大标签以及SEO优化
- Title(标题):标题是内页的第一个重要标签,是搜索引擎了解网页的入口和对网页主题归属的最佳判断点。建议使用网站名(产品名)- 网站的介绍,且字数不要超过30个汉字。
- Description(描述):描述简要说明网站主要是做什么的,作为网站的总业务和主题概括。建议采用“我们是…”、“我们提>供…”、“xxx网作为…”、“”的形式。
- Keywords(关键词):关键词是页面关键词,是搜索引擎的关注点之一。建议限制为6~8个关键词,关键词之间用英文逗>号隔开,采用关键词1,关键词2的形式。
SEO优化是通过对网站进行深度的优化,从而帮助网站获取免费的流量,进而在搜索引擎上提升网站的排名,提高网站的知名度。在进行SEO优化时,需要关注以下几个方面:
- 关键词研究:了解目标受众的搜索习惯,选择合适的关键词,并合理地将其分布在网站的TDK中。
- 内容质量:提供有价值、独特、高质量的内容,吸引用户并提高用户体验。
- 页面结构:优化页面结构,使其易于理解和导航,提高页面加载速度。
- 链接建设:获取高质量的外部链接,提高网站的权威性和排名。
- 网站结构:合理规划网站结构,使其符合搜索引擎的爬虫和索引规则。
总之,网站TDK三大标签是SEO优化的基础,通过合理设置TDK标签,结合其他SEO优化策略,可以提高网站在搜索引擎中的排名,从而吸引更多的流量。
JS
1.js的数据类型
数据类型分为两种:基本数据类型与引用数据类型。基本数据类型有:number、string、boolean、null、undefined。引用数据类型有:array、function等(除了基本数据类型都是引用数据类型)
基本数据类型的主要特点是赋值方式是传值,并且值存在栈中。
引用数据类型的主要特点是赋值方式是传址,并且值存在堆中。
2.双等和三等的区别
在JavaScript中,双等()和三等(=)是用于比较两个值的操作符。
双等(==)用于比较两个值是否相等,但它会进行类型转换。如果两个值的类型不同,JavaScript会尝试将它们转换为相同的类型,然后再进行比较。这种类型转换可能会导致一些意外的结果。例如:
console.log(1 == '1'); // true,因为字符串'1'被转换为数字1
console.log(true == 1); // true,因为布尔值true被转换为数字1
console.log(null == undefined); // true,因为它们被认为是相等的特殊情况
三等(===)也用于比较两个值是否相等,但它不进行类型转换。只有当两个值的类型和值都相等时,才会返回true。例如:
console.log(1 === '1'); // false,因为它们的类型不同
console.log(true === 1); // false,因为它们的类型不同
console.log(null === undefined); // false,因为它们的类型不同
因此,使用双等()进行比较时,需要注意可能的类型转换和意外结果。为了避免这种情况,最好使用三等(=)进行严格的类型和值比较。
3.js中布尔值为false的几种情况
- false:布尔字面量false表示假。
- 0:数字0被视为假。
- NaN:NaN(Not a Number)表示非数字,被视为假。
- 空字符串:空字符串""被视为假。
- null:null表示空值,被视为假。
- undefined:undefined表示未定义的值,被视为假。
4.let const var 区别
在编程中,“let”、"const"和"var"是用于声明变量的关键字,它们之间有一些区别。
-
var:在ES5及之前的JavaScript版本中,使用"var"关键字声明变量是最常见的方式。它具有函数作用域,意味着变量的作用域限定在声明它的函数内部。如果在函数内部使用"var"声明的变量没有使用关键字进行限定,那么它将成为全局变量。
-
let:在ES6中引入了"let"关键字,它具有块级作用域。块级作用域意味着变量的作用域限定在声明它的代码块内部,例如if语句、for循环等。使用"let"声明的变量只在当前代码块内有效,不会污染全局作用域。
-
const:"const"也是在ES6中引入的关键字,用于声明常量。与"let"类似,"const"也具有块级作用域,但它声明的变量必须进行初始化,并且不能再次赋值。这意味着一旦用"const"声明一个变量,它的值就不能再改变。
总结来说,"var"具有函数作用域,"let"和"const"具有块级作用域。"let"声明的变量可以重新赋值,而"const"声明的变量不能重新赋值。在实际开发中,推荐使用"let"和"const"来声明变量,因为它们更安全、更易于维护。
5.普通函数和箭头函数的区别
普通函数和箭头函数是JavaScript中两种不同的函数定义方式,它们有以下几个区别:
- 语法结构:普通函数使用function关键字来定义,而箭头函数使用箭头(=>)来定义。
- this的指向:普通函数中的this指向调用该函数的对象,而箭头函数中的this指向定义时的上下文,即外层作用域的this。
- arguments对象:普通函数中可以使用arguments对象来获取传入的参数列表,而箭头函数没有自己的arguments对象,它会继承外层作用域的arguments对象。
- 构造函数:普通函数可以用作构造函数来创建对象实例,而箭头函数不能使用new关键字来创建对象实例。
- 返回值:普通函数中可以使用return语句来返回值,而箭头函数可以使用简洁的箭头函数表达式来隐式返回值。
总的来说,普通函数更适合作为方法、构造函数或需要动态绑定this的场景,而箭头函数更适合简洁的函数表达式和回调函数的场景。
6.数组有哪些方法
数组是一种常见的数据结构,它可以存储多个相同类型的元素。在大多数编程语言中,数组都提供了一些常用的方法来操作和处理数组。以下是一些常见的数组方法:
- length:返回数组的长度(元素个数)。
- push:向数组末尾添加一个或多个元素。
- pop:删除并返回数组的最后一个元素。
- shift:删除并返回数组的第一个元素。
- unshift:向数组的开头添加一个或多个元素。
- concat:将两个或多个数组合并成一个新数组。
- slice:返回指定位置的子数组。
- splice:删除、替换或插入元素到数组的指定位置。
- indexOf:返回指定元素在数组中的第一个匹配位置的索引。
- lastIndexOf:返回指定元素在数组中的最后一个匹配位置的索引。
- forEach:对数组的每个元素执行指定的操作。
- map:对数组的每个元素执行指定的操作,并返回一个新数组。
- filter:根据指定的条件筛选数组的元素,并返回一个新数组。
- reduce:对数组的元素进行累积操作,返回一个结果。
- sort:对数组的元素进行排序。
- reverse:反转数组的顺序。
这只是一些常见的数组方法,不同的编程语言可能会提供更多的方法。在实际编程中,可以根据具体需求选择合适的数组方法来操作和处理数组。
7.for in 对比 for of区别
在JavaScript中,for...in
和for...of
是两种不同的循环语句,用于遍历对象和数组。
for...in
循环用于遍历对象的可枚举属性。它会迭代对象的所有可枚举属性,包括原型链上的属性。语法如下:
例如,我们可以使用for...in
循环遍历一个对象的属性:
const obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
console.log(key); // 输出:a, b, c
console.log(obj[key]); // 输出:1, 2, 3
}
for...of
循环用于遍历可迭代对象(如数组、字符串、Set、Map等)。它会迭代对象的可迭代属性,而不包括原型链上的属性。语法如下:
例如,我们可以使用for...of
循环遍历一个数组:
const arr = [1, 2, 3];
for (let value of arr) {
console.log(value); // 输出:1, 2, 3
}
总结:
for...in
循环用于遍历对象的可枚举属性。for...of
循环用于遍历可迭代对象的可迭代属性。
8.扁平化数组代码实现
在JavaScript中,flat()
方法用于将多维数组扁平化为一维数组。该方法会将嵌套的数组展开,并返回一个新的一维数组。
flat()
方法可以接受一个可选的参数,用于指定要展开的嵌套层数。如果不传递参数,默认展开所有层级。
以下是flat()
方法的示例用法:
const arr = [1, 2, [3, 4, [5, 6]]];
const flattenedArr = arr.flat();
console.log(flattenedArr); // [1, 2, 3, 4, 5, 6]
const arr2 = [1, 2, [3, 4, [5, 6]]];
const flattenedArr2 = arr2.flat(2);
console.log(flattenedArr2); // [1, 2, 3, 4, 5, 6]
需要注意的是,flat()
方法是ES2019引入的新方法,不是所有的浏览器都支持。如果需要在不支持的环境中使用,可以使用polyfill或者其他替代方法来实现类似的功能。
.9数组去重的方法
arr=[1,5,1,3,5,4,3,9,8]
let mySet = new Set(arr); // 非重复的类数组
console.log(mySet,'mySet');//{{1, 5, 3, 4, 9,8}
// let newArr = Array.from(mySet); // set转数组
let newArr = [...mySet]; // 或者是这种解构方法
console.log(newArr);//[1, 5, 3, 4, 9, 8]
10.防抖和节流
防抖:Debounce将前面所有触发取消,最后一次执行规定时间内才能触发,也就是说如果连续触发只能执行一次,(大部分应用场景搜索框等)
<template>
<div>
<el-input v-model="inputVal" placeholder="请输入内容" @input="inputChange"></el-input>
</div>
</template>
<script>
//引入lodash
import lodash from "lodash";
export default {
name: "HelloWorld",
data() {
return {
inputVal: "",
};
},
methods: {
inputChange: lodash.debounce(function (val) {
console.log("---输入框内容(lodash)---", val); //业务逻辑
console.log("---发送请求---"); //业务逻辑
}, 1000),
},
};
</script>
节流:throttle将在规定的间隔时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发(列如查询五秒内只能使用一次)
<template>
<div class="main">
<el-button type="plain" @click="search">搜索</el-button>
</div>
</template>
<script>
import lodash from "lodash";
export default {
name: "HelloWorld",
methods: {
search: lodash.throttle(
function () {
console.log("---发送请求---"); //业务逻辑
},
3000,
{ trailing: false } //一定要传入这个参数否则的话在3秒内多次点击会调用2次
),
},
};
</script>
10.事件循环机制
事件循环理论先执行同步任务,再去执行我们的异步任务(先执行微任务再执行宏任务)。
异步任务进一步划分分为:
宏任务:script标签、setTimeout()、setInterval
微任务:Promise.then、nextTick
11.原型与原型链
原型(prototype)是JavaScript中的一个概念,它是一个对象,其他对象可以通过它进行属性和方法的继承。每个JavaScript对象都有一个原型,可以通过__proto__
属性来访问。
原型链(prototype chain)是指当访问一个对象的属性或方法时,如果该对象本身没有该属性或方法,JavaScript引擎会沿着原型链向上查找,直到找到该属性或方法或者到达原型链的顶端(即Object.prototype)。
当我们创建一个对象时,JavaScript会自动为该对象关联一个原型。我们可以通过构造函数来创建对象,构造函数中的prototype
属性就是该构造函数创建的对象的原型。当我们使用new
关键字创建一个对象时,该对象的原型就是构造函数的prototype
属性。
例如,我们有一个构造函数Person
,它有一个name
属性和一个sayHello
方法:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log("Hello, my name is " + this.name);
}
var person1 = new Person("Alice");
person1.sayHello(); // 输出:Hello, my name is Alice
在上面的例子中,person1
对象通过new Person("Alice")
创建,它的原型是Person.prototype
。当我们调用person1.sayHello()
时,JavaScript引擎会先在person1
对象中查找sayHello
方法,如果找不到,就会沿着原型链向上查找,最终找到Person.prototype
中的sayHello
方法并执行。
这就是原型和原型链的基本概念和用法。它们是JavaScript中实现继承的重要机制。
12.localStorage、sessionStorage、cookie区别
localStorage、sessionStorage和cookie是用于在浏览器端存储数据的三种不同的机制。
-
localStorage:localStorage是HTML5引入的一种持久化存储机制,它可以在浏览器关闭后仍然保留数据。存储在localStorage中的数据没有过期时间,除非手动清除或者通过代码删除,否则数据将一直存在。localStorage可以存储大量的数据,一般有5MB或更大的容量限制。
-
sessionStorage:sessionStorage也是HTML5引入的一种存储机制,它与localStorage相似,但是存储在sessionStorage中的数据在浏览器关闭后会被清除。sessionStorage的作用域是在当前会话中,即同一个浏览器窗口或者标签页。sessionStorage的容量限制与localStorage相同。
-
cookie:cookie是一种在浏览器端存储数据的机制,它可以设置过期时间。存储在cookie中的数据会在每次请求时发送到服务器端,因此可以用于实现用户登录状态的保持。cookie的容量限制较小,一般为4KB左右。
总结:
- localStorage和sessionStorage都是在浏览器端存储数据的机制,可以用于在不同页面之间共享数据。
- localStorage的数据在浏览器关闭后仍然保留,而sessionStorage的数据在浏览器关闭后会被清除。
- cookie可以设置过期时间,并且在每次请求时会发送到服务器端,适合用于实现用户登录状态的保持。
13.typeof 和 instanceof 他们两者的区别
1.typeof:一般判断基本数据类型
2.instanceof :一般判断引用类型数据,主要的作用就是判断一个实例是否属于某种类型,或者判断一个实例是否有它的原型。
14.null typeof为什么是一个object
因为在javaScript中,不同的对象都是使用二进制存储的,如果二进制前三位都是0的话,系统会判断为是Object类型,而null的二进制全是0,自然也就判断为Object
15.JS闭包
闭包是JavaScript中一种强大的特性,它可以让函数访问其外部作用域中的变量和函数。闭包有以下几个优点和缺点:
优点:
- 保护变量:闭包可以将变量私有化,防止其被外部访问和修改,提高代码的安全性。
- 延长变量生命周期:闭包可以使函数中的变量在函数执行完毕后仍然存在,可以在之后的调用中继续使用,提供了一种保存状态的机制。
- 实现模块化:闭包可以将一组相关的变量和函数封装在一个作用域内,形成一个独立的模块,提高代码的可维护性和可复用性。
缺点:
- 内存泄漏:闭包中的变量会一直存在于内存中,如果闭包被频繁创建且不被释放,可能会导致内存泄漏问题。
- 性能问题:闭包会占用更多的内存和处理时间,因为它需要维护额外的作用域链和变量引用关系。
- 难以理解和调试:闭包的嵌套结构和变量引用关系可能会增加代码的复杂性,使得代码难以理解和调试。
总的来说,闭包是一种强大的特性,但在使用时需要注意内存和性能问题,合理使用闭包可以提高代码的可维护性和可复用性。
16.js什么是深拷贝?什么是浅拷贝
深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是在编程中常用的两个概念,用于描述对象或数据的复制方式。
深拷贝是指创建一个新的对象或数据,完全复制原始对象或数据的所有值和内容。深拷贝会递归地复制所有的子对象,确保原始对象和新对象之间的完全独立性。即使原始对象发生变化,新对象也不会受到影响。
浅拷贝是指创建一个新的对象或数据,只复制原始对象或数据的引用而不是实际的值和内容。浅拷贝只复制对象的第一层,而不会递归复制子对象。因此,如果原始对象包含引用类型的属性,浅拷贝后的对象和原始对象会共享这些属性的引用,导致它们之间的变化相互影响。
在编程中,深拷贝和浅拷贝的选择取决于具体的需求和场景。如果需要独立的对象或数据,不希望它们之间相互影响,就应该使用深拷贝。如果只需要引用原始对象或数据的副本,并且可以接受它们之间的相互影响,就可以使用浅拷贝。
17.如何避免前端请求明文传输
HTTPS 加密传输: 使用 HTTPS
协议发送请求,所有的数据都会在传输过程中进行加密,从而保护数据不以明文形式传输。这样即使数据被截获,黑客也无法直接获取到数据的内容。
数据加密处理:
在前端对敏感数据进行加密处理,然后再发送请求。可以使用一些加密算法,如 AES、RSA
等,将敏感数据进行加密后再发送到服务器。这样即使数据在传输过程中被截获,也无法直接获取其内容。
请求签名验证:
在发送请求之前,前端对请求参数进行签名处理,并将签名结果和请求一起发送到服务器。服务器端根据事先约定的签名算法和密钥对请求参数进行验证,确保请求的完整性和可靠性。
Token 验证:
在用户登录时,后端会生成一个 Token 并返回给前端,前端在发送请求时需要将 Token
添加到请求头或请求参数中。后端在接收到请求后,验证 Token 的有效性,以确保请求的合法性。
请求头加密处理:
在发送请求时,可以将请求头中的一些关键信息进行加密处理,然后再发送到服务器。服务器端需要在接收到请求后对请求头进行解密,以获取其中的信息。
18.轮询
轮询(Polling)是一种网络通信技术,用于定期向服务器发送请求以获取最新数据。
所谓的轮询就是,由后端维护某个状态,或是一种连续多篇的数据(如分页、分段),由前端决定按序访问的方式将所有片段依次查询,直到后端给出终止状态的响应(结束状态、分页的最后一页等)。
一般有两种解决方案:一种是使用websocket,可以让后端主动推送数据到前端;还有一种是前端主动轮询(上网查了下细分为长轮询和短轮询),通过大家熟悉的定时器(setInterval和setTimeout)实现。
什么情况一下可以使用websocket 什么情况下使用setInterval和setTimeout
何时使用 WebSocket
- 实时性要求高:当需要实时接收服务器端的数据更新时,例如实时聊天、实时通知、在线游戏等场景,使用 WebSocket 是更好的选择。
- 双向通信:当需要在客户端和服务器之间进行双向实时通信时,例如在线聊天室、协同编辑、远程控制等场景,使用 WebSocket 更加合适。
- 降低服务器负载:WebSocket 使用持久连接,减少了服务器的连接建立和关闭开销,从而降低了服务器负载。
何时使用 setInterval 和 setTimeout
- 轮询:当服务器端不支持 WebSocket,或者需要定期向服务器发送请求以获取数据时,可以使用
setInterval
或setTimeout
进行轮询。例如,定期检查服务器上的文件更新、定期获取服务器端的状态信息等场景。- 定时执行任务:当需要在特定的时间间隔内执行某个任务时,可以使用
setInterval
或setTimeout
。例如,每隔 1 小时自动刷新页面、每天凌晨自动清理缓存等场景。总结 WebSocket 和
setInterval
/setTimeout
分别适用于不同的场景。WebSocket 更适合实时性要求高、需要双向通信的场景;而setInterval
和setTimeout
更适合轮询和定时执行任务的场景。在选择使用哪种技术时,需要根据实际需求和场景来决定。如果可能的话,优先选择
WebSocket,因为它可以提供更好的实时性和效率。
详细介绍 轮询websocket
19.pnpm npm cnpm yarn的特点,他们之前的区别是有哪些?
pnpm
、npm
、cnpm
和yarn
都是用于管理JavaScript项目依赖的包管理器。以下是它们之间的区别:
npm:
- 特点:npm是Node.js的默认包管理器,与Node.js一起安装,拥有庞大的包生态系统。
- 使用实例:
npm install lodash
、npm install -g create-react-app
、npm list
、npm cache clean
。 - 优势:广泛使用,易于上手,有大量的开源包和第三方包可用。
- 劣势:可能导致依赖项重复安装,占用较多磁盘空间。
pnpm:
- 特点:pnpm是npm的一个替代品,旨在通过共享依赖项减少磁盘空间占用。
- 使用实例:
pnpm install lodash
、pnpm install -g create-react-app
、pnpm list
、pnpm cache clean
。 - 优势:快速、轻量级、节省磁盘空间,通过硬链接和软链接管理依赖项。
- 劣势:相对较新,社区规模相对较小。
cnpm:
- 特点:cnpm是淘宝团队开发的一个npm镜像源,针对中国用户,提供更快的下载速度。
- 使用实例:
cnpm install lodash
、cnpm install -g create-react-app
、cnpm list
、cnpm cache clean
。 - 优势:提高下载速度,适用于国内网络环境。
- 劣势:本质上仍然是npm,可能受到npm的一些限制。
yarn:
- 特点:yarn由Facebook维护,提供了更快、更可靠的安装体验,通过并行下载和版本锁定来优化性能。
- 使用实例:
yarn add lodash
、yarn global add create-react-app
、yarn list
、yarn cache clean
。 - 优势:高性能,更好的依赖管理,支持并行下载和版本锁定。
- 劣势:可能与某些npm包不完全兼容。
总结:
- npm是Node.js的默认包管理器,拥有庞大的生态系统,但可能导致依赖项重复安装和占用较多磁盘空间。
- pnpm是npm的替代品,通过共享依赖项减少磁盘空间占用,适用于需要优化空间的项目。
- cnpm是npm的镜像源,针对中国用户,提高下载速度。
- yarn由Facebook维护,提供高性能的依赖管理,支持并行下载和版本锁定。
20.JS中 i++ 和 ++i 有什么区别?
在JavaScript中,i++
和++i
都是用于递增变量i
的值的操作符,但它们之间存在一些差异
- i++(后置递增)
i++
是后置递增操作符,它首先返回变量i
的当前值,然后将i
的值加1。这意味着在表达式中使用i++
时,它的值将在递增之后的某个时间点更新。
例如:
let i = 0;
let j = i++; // j的值为0,i的值变为1
- ++i(前置递增)
++i
是前置递增操作符,它首先将变量i
的值加1,然后返回新值。这意味着在表达式中使用++i
时,它的值将立即更新。
例如:
let i = 0;
let j = ++i; // j的值为1,i的值也变为1
总结:i++
和++i
都会使变量i
的值加1,但在表达式中使用它们时,它们的返回值有所不同。i++
返回递增之前的值,而++i
返回递增之后的值。在大多数情况下,这种差异对程序的执行结果影响不大,但在某些特定场景中,这种差异可能会导致不同的行为。
VUE
前瞻
vue的设计理念是什么,你说理解的vue是什么样的,他的底层原理可以讲讲吗
Vue.js的设计理念是基于数据驱动视图的思想,它通过数据绑定、组件化、指令等技术实现了一个高度可复用、易于维护的前端框架。Vue.js的核心是一个允许你使用数据对象来驱动UI的系统,它会自动将数据与UI进行同步,只要数据发生变化,UI就会自动更新。
Vue.js的主要特点包括:
响应式数据绑定:Vue.js通过数据绑定将数据与视图关联起来,当数据发生变化时,视图会自动更新。
组件化:Vue.js提供了组件化的开发方式,可以将页面拆分成多个独立的、可复用的组件,提高代码的可维护性和可复用性。
指令:Vue.js提供了一些内置的指令,如v-if、v-for、v-bind等,用于处理常见的UI逻辑。
过渡效果:Vue.js提供了过渡效果的支持,可以方便地为元素的插入、更新和移除添加动画效果。
易于集成:Vue.js可以很容易地与其他库或现有项目集成,同时也提供了一套完整的生态系统,包括Vue Router、Vuex等。
Vue.js的底层原理主要包括以下几个方面:
数据劫持:Vue.js通过数据劫持的方式实现数据与视图的双向绑定。它使用了Object.defineProperty()方法对数据对象的每个属性进行了劫持,并添加了getter和setter函数。当数据发生变化时,setter函数会被触发,从而通知视图进行更新;当视图需要读取数据时,getter函数会被触发,从而将数据返回给视图。
虚拟DOM:Vue.js使用了虚拟DOM技术,将真实DOM抽象成一个JavaScript对象,这个对象包含了DOM的所有信息,如标签名、属性、子节点等。当数据发生变化时,Vue.js会先更新虚拟DOM,然后通过对比新旧虚拟DOM的差异,找出需要更新的部分,最后批量更新到真实DOM中。这种方式可以减少对真实DOM的操作,提高性能。
模板编译:Vue.js将模板编译成虚拟DOM渲染函数。在首次渲染时,Vue.js会将模板编译成一个渲染函数,该函数包含了如何将数据渲染成虚拟DOM的逻辑。在后续的更新过程中,Vue.js会直接使用这个渲染函数生成新的虚拟DOM,然后进行更新。
依赖收集:Vue.js通过依赖收集的方式实现数据与视图的关联。当视图读取数据时,依赖收集会将视图与数据之间的关系记录下来。当数据发生变化时,Vue.js会通知相关的视图进行更新。
组件化:Vue.js提供了组件化的开发方式,可以将页面拆分成多个独立的、可复用的组件。组件之间可以通过props传递数据,通过事件进行通信。这种方式可以提高代码的可维护性和可复用性。
Vue中的虚拟DOM是如何工作的?
虚拟DOM(Virtual
DOM)是Vue.js中一个非常重要的概念,它是对真实DOM的抽象,用JavaScript对象来表示DOM结构。虚拟DOM的工作原理主要包括以下几个方面:
创建虚拟DOM:当Vue.js实例化时,会将模板编译成虚拟DOM。虚拟DOM是一个树状结构,每个节点表示一个DOM元素或组件,包含了元素或组件的属性、子节点等信息。
渲染虚拟DOM:Vue.js会将虚拟DOM渲染成真实DOM,并插入到页面中。这个过程是在首次渲染时完成的。
更新虚拟DOM:当数据发生变化时,Vue.js会先更新虚拟DOM。这个过程是通过数据劫持和依赖收集实现的。当数据发生变化时,会触发setter函数,从而通知相关的视图进行更新。
对比新旧虚拟DOM:Vue.js会先保存当前的虚拟DOM,然后根据新的数据生成一个新的虚拟DOM。接着,Vue.js会对比新旧虚拟DOM的差异,找出需要更新的部分。
批量更新真实DOM:Vue.js会将需要更新的部分批量更新到真实DOM中。这个过程是通过一种叫做"最小渲染"的策略实现的。Vue.js会先计算出需要更新的最小DOM集合,然后一次性将这些DOM更新到页面中。这种方式可以减少对真实DOM的操作,提高性能。
通过以上五个步骤,Vue.js实现了虚拟DOM的工作原理。虚拟DOM的优势在于它将DOM操作的性能成本降到了最低,同时也提高了开发效率,因为开发者只需要关注数据和视图的逻辑,而不需要关心底层的DOM操作。
1、vue生命周期
vue2生命周期函数
beforeCreate、created 、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed | |
---|---|
vue3生命周期函数
setup 、onBeforeMount 、 onMounted 、onBeforeUpdate 、onUpdated、onBeforeUnmount、onUnmounted | |
---|---|
-
生命周期钩子函数名称的变化:
- Vue.js 2中的beforeCreate和created钩子函数在Vue.js 3中被重命名为beforeSetup和setup。
- Vue.js 2中的beforeMount和mounted钩子函数在Vue.js 3中被重命名为beforeMount和onMounted。
- Vue.js 2中的beforeUpdate和updated钩子函数在Vue.js 3中被重命名为beforeUpdate和onUpdated。
- Vue.js 2中的beforeDestroy和destroyed钩子函数在Vue.js 3中被重命名为beforeUnmount和onUnmounted。
-
新增的生命周期钩子函数:
- Vue.js 3引入了一些新的生命周期钩子函数,如beforeUnmount、onUnmounted、beforeUpdate、onUpdated等。这些钩子函数提供了更精细的控制和更好的性能优化。
-
Composition API的引入:
- Vue.js 3引入了Composition API,它是一种新的组合式API,可以更好地组织和重用组件逻辑。与Vue.js 2的Options API相比,Composition API提供了更灵活和可组合的方式来编写代码,从而改变了组件的生命周期使用方式。
总的来说,Vue.js 3在生命周期方面进行了一些改进和优化,引入了新的钩子函数和Composition API,提供了更好的性能和更灵活的开发方式。
2.vue的特性
共同特性:
- 声明式渲染:Vue使用模板语法将组件的状态映射到DOM元素,使得开发者可以轻松地编写和理解代码。
- 组件化开发:Vue将应用程序拆分为多个可重用的组件,使得代码更加模块化和可维护。
- 响应式数据绑定:Vue使用双向绑定机制,当数据发生变化时,自动更新相关的视图。
- 虚拟DOM:Vue使用虚拟DOM来提高性能,只更新需要变化的部分,而不是整个DOM树。
Vue2的特性:
- 过滤器:Vue2支持过滤器,可以在模板中对数据进行格式化和处理。
- mixins:可以将多个组件共享的逻辑提取为mixin,减少重复代码。
- keep-alive:可以使用keep-alive组件缓存组件的状态,提高性能。
Vue3的特性:
- Composition API:Vue3引入了Composition API,提供了更灵活和可组合的方式来组织和重用组件逻辑。
- 更好的性能:Vue3在虚拟DOM的实现上进行了优化,提高了性能。
- 更小的体积:Vue3的体积比Vue2更小,加载速度更快。
- TypeScript支持:Vue3对TypeScript的支持更加完善,提供了更好的类型检查和开发体验。
3.vue数据的双向绑定
在Vue2中,数据双向绑定是通过使用Object.defineProperty()方法来实现的。当数据发生变化时,Vue会通过劫持数据的getter和setter方法来监听数据的变化,并且在数据变化时更新相关的视图。这种方式需要对每个数据进行劫持,因此在大规模数据变化时会有一定的性能问题。
而在Vue3中,采用了Proxy对象来实现数据双向绑定。Proxy对象可以直接监听整个对象的变化,而不需要对每个属性进行劫持。当数据发生变化时,Proxy对象会触发相应的代理方法,从而更新相关的视图。这种方式相比Vue2的方式更加高效,尤其在处理大规模数据变化时性能更好。
4.为什么vue被称为单页面应用,说说你对单页面应用这个词的理解
Vue.js被称为单页面应用(Single Page Application,简称SPA)框架,原因在于它主要关注的是在一个单一的HTML页面上通过动态更新内容来实现用户交互,而不是通过传统的多页面跳转方式。这种设计模式带来了许多优点,同时也有一些潜在的缺点。
单页面应用(SPA)的理解:
-
单一HTML页面:SPA在一个HTML文件中包含所有内容,而不是为每个页面单独创建HTML文件。所有的页面切换和内容更新都在这个单一页面上完成。
-
动态内容更新:SPA通过JavaScript动态地更新页面内容,而不是通过服务器重新加载整个页面。这意味着页面的状态可以在不重新加载整个页面的情况下进行更改。
-
用户体验:SPA通常提供更流畅的用户体验,因为页面之间的切换非常快速且不需要完全重新加载页面。这有助于减少用户在等待页面加载时的不耐烦感。
-
前后端分离:SPA常常与前后端分离的开发模式相结合。在这种模式下,前端负责展示和交互,而后端负责处理业务逻辑和数据存储。这使得前后端可以独立开发和部署,提高了开发效率。
-
路由管理:SPA通常需要一个客户端路由系统来管理页面间的导航。Vue Router就是Vue.js中用于管理SPA路由的一个官方库。
然而,SPA也有一些潜在的缺点:
-
首次加载时间较长:由于所有页面内容都包含在一个HTML文件中,SPA的首次加载时间可能会比较长,尤其是在网络连接较慢的情况下。
-
SEO优化:SPA的内容是通过JavaScript动态加载的,这可能导致搜索引擎爬虫无法正确索引页面内容。为了解决这个问题,可以使用服务端渲染(SSR)或预渲染(Prerendering)等技术。
-
兼容性问题:SPA依赖于JavaScript来呈现页面内容,因此在一些较低版本或禁用JavaScript的浏览器中可能无法正常工作。
总的来说,Vue.js作为一个单页面应用框架,提供了一种现代、高效的方式来构建用户界面,但也需要注意其潜在的问题并采取相应的解决方案。
React
1.你了解reac吗,他t的设计理念是什么,他的底层原理可以讲讲吗, 和vue有什么区别,又有什么共同点
React是一个由Facebook开发的用于构建用户界面的JavaScript库,它的设计理念是“组件化”和“单向数据流”。
在React中,组件是构建应用程序的基本单元,它们可以封装自己的状态和行为,并且可以通过属性(props)接收来自父组件的数据和函数。这种组件化的设计使得代码更加模块化和可复用。
单向数据流是指数据在组件之间的流动方向,它从父组件流向子组件,而不是相反。这种单向数据流的设计有助于维护应用程序的状态和逻辑,并且使得代码更加易于理解和调试。
React的底层原理是基于虚拟DOM(Virtual
DOM)的。虚拟DOM是一个轻量级的JavaScript对象,它代表了真实的DOM结构。当组件的状态发生变化时,React会使用虚拟DOM算法来计算出最小的DOM更新操作,然后将这些操作应用到真实的DOM上,从而实现高效的UI更新。React和Vue都是流行的JavaScript框架,它们有一些相似之处,也有一些不同之处。
相似之处包括:
- 都支持组件化开发。
- 都使用虚拟DOM来实现高效的UI更新。
- 都提供了状态管理工具(React使用Redux,Vue使用Vuex)。
不同之处包括:
- 数据绑定方式不同。React使用单向数据流,而Vue使用双向数据流。
- 模板语法不同。React使用JSX,而Vue使用模板语法。
- 状态管理方式不同。React使用Redux,而Vue使用Vuex。
- 生态系统不同。React的生态系统更加庞大,而Vue的生态系统相对较小,但更加简单和易用。
总的来说,React和Vue都是优秀的JavaScript框架,它们都有自己的优点和适用场景。选择哪个框架取决于项目需求和开发团队的熟悉程度。
2.React和Vue在虚拟DOM中有什么不同?
- 组件依赖关系跟踪:Vue会跟踪每个组件的依赖关系,这意味着当某个组件的状态发生变化时,Vue只会更新与该组件直接相关的部分,而不是整个组件树。这有助于减少不必要的渲染,提高性能。而React在状态发生改变时,会重新渲染整个组件树,然后使用diff算法来比较新旧虚拟DOM的差异,从而更新真实DOM。
- 组件更新策略:React采用自顶向下的全量diff策略,这意味着当状态发生改变时,React会重新渲染整个组件树,然后使用diff算法来比较新旧虚拟DOM的差异,从而更新真实DOM。而Vue采用增量更新策略,只会更新与状态变化直接相关的部分。
- 组件写法:React推荐使用JSX和内联样式,将HTML和CSS都写入JavaScript中。而Vue推荐使用template的单文件组件格式,将HTML、CSS和JavaScript写在同一个文件中。Vue也支持JSX写法,但它的主要设计思路是易于理解和学习。
总的来说,React和Vue在虚拟DOM中的主要区别在于它们处理组件更新和依赖关系的方式,以及它们的组件写法。这些差异反映了它们在设计理念和实践方法上的不同。
3.React的diff算法是如何工作的?
React的diff算法是一种高效的算法,用于比较新旧虚拟DOM的差异,从而确定需要更新的真实DOM。React的diff算法采用了一种称为“Reconciliation”的策略,它的主要思想是在新旧虚拟DOM之间找到最小的差异,并将这些差异应用到真实DOM上。
React的diff算法的工作原理如下:
- 逐层比较:React首先会比较新旧虚拟DOM的根节点,如果根节点不同,则会替换整个真实DOM树。如果根节点相同,则会继续比较子节点。
- 列表比较:对于列表类型的子节点,React会使用一种称为“key”的属性来标识每个子节点。当列表发生变化时,React会根据key来判断哪些子节点是新增的、哪些子节点是删除的、哪些子节点是移动的。这有助于React更准确地找到最小的差异,并更新真实DOM。
- 元素属性比较:对于每个子节点,React会比较它们的属性,如class、style、onClick等。如果属性发生变化,React会更新真实DOM的相应属性。
- 组件比较:对于自定义组件,React会比较组件的props和state。如果props或state发生变化,React会重新渲染组件,并使用diff算法来比较新旧虚拟DOM的差异,从而更新真实DOM。
React的diff算法采用了一种称为“最长公共子序列”的算法来比较列表类型的子节点。这种算法的时间复杂度为O(n),其中n为子节点的数量。这使得React的diff算法在处理大量子节点时仍然能够保持较高的性能。
总的来说,React的diff算法是一种高效的算法,它通过逐层比较、列表比较、元素属性比较和组件比较等方式,来找到新旧虚拟DOM之间的最小差异,并将这些差异应用到真实DOM上。这使得React能够在保持高性能的同时,实现高效的UI更新。
-
请解释React中的虚拟DOM(Virtual DOM)是什么,以及它的作用。
- 虚拟DOM是React中的一个核心概念,它是一个轻量级的JavaScript对象,用于表示真实的DOM结构。虚拟DOM的作用是允许React在不直接操作真实DOM的情况下,快速地计算出UI应该发生的改变。当组件的状态发生变化时,React会更新虚拟DOM,然后通过diff算法比较新旧虚拟DOM的差异,并最终将这些差异应用到真实DOM上。
-
React中的组件生命周期有哪些阶段,以及每个阶段对应的方法有哪些?
- React组件的生命周期可以分为三个主要阶段:挂载(Mounting)、更新(Updating)和卸载(Unmounting)。挂载阶段包括
constructor
、render
、componentDidMount
等方法;更新阶段包括render
、componentDidUpdate
、shouldComponentUpdate
等方法;卸载阶段只有一个componentWillUnmount
方法。
- React组件的生命周期可以分为三个主要阶段:挂载(Mounting)、更新(Updating)和卸载(Unmounting)。挂载阶段包括
-
请解释React中的state和props,以及它们之间的区别。
state
是组件内部的状态管理系统,用于存储组件的内部数据。当state发生变化时,React会重新渲染组件。props
则是组件间传递数据的一种方式,父组件通过props向子组件传递数据。与state不同,props是只读的,子组件不能直接修改props的值。
-
React中的高阶组件(Higher-Order Components, HOCs)是什么,以及它们的用途。
- 高阶组件是接受一个组件作为参数并返回一个新组件的函数。HOCs主要用于复用组件逻辑,例如认证、错误处理、数据获取等。通过HOCs,我们可以将这些逻辑抽离出来,避免在组件内部重复编写相同的代码。
-
请解释React中的受控组件(Controlled Components)和非受控组件(Uncontrolled Components)的区别。
- 受控组件是指其值由React state控制的表单元素,例如
<input>
、<textarea>
和<select>
等。当用户在这些元素中输入数据时,React会更新相应的state。非受控组件则是指其值由DOM本身管理的表单元素,通常使用ref
来访问DOM元素并获取其值。
- 受控组件是指其值由React state控制的表单元素,例如
-
React中的Context API是什么,以及它在什么场景下使用?
- Context API是React提供的一种全局状态管理方式,允许我们在组件树中的任意位置访问和更新共享数据,而无需通过props逐层传递。Context API主要用于那些需要在多个组件之间共享状态的场景,例如主题设置、用户认证信息等。
-
请解释React中的Hooks以及它们如何改变组件开发的方式。
- Hooks是React 16.8版本引入的新特性,允许我们在不编写class的情况下使用state和其他React特性。通过使用
useState
、useEffect
、useContext
等Hooks,我们可以将组件逻辑抽离到可重用的函数中,使组件更加简洁和易于理解。
- Hooks是React 16.8版本引入的新特性,允许我们在不编写class的情况下使用state和其他React特性。通过使用
-
React中的性能优化策略有哪些?
- React中的性能优化策略包括:使用
React.memo
或PureComponent
进行浅比较以避免不必要的渲染;使用React.lazy
和Suspense
实现代码分割和懒加载;避免不必要的state更新;使用shouldComponentUpdate
或React.memo
自定义渲染条件等。
- React中的性能优化策略包括:使用
-
请解释React Router的工作原理,并给出一个简单的路由配置示例。
- React Router是一个基于React之上的路由库,它允许我们通过声明式的方式配置路由。React Router的工作原理是通过监听URL的变化,并根据配置的路由规则渲染相应的组件。一个简单的路由配置示例可能包括:
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import Home from './pages/Home'; import About from './pages/About'; import NotFound from './pages/NotFound'; function App() { return ( <Router> <Switch> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> <Route component={NotFound} /> </Switch> </Router> ); } export default App;
- React Router是一个基于React之上的路由库,它允许我们通过声明式的方式配置路由。React Router的工作原理是通过监听URL的变化,并根据配置的路由规则渲染相应的组件。一个简单的路由配置示例可能包括:
-
React和Vue在组件设计和状态管理方面有哪些主要区别?
- React和Vue在组件设计和状态管理方面的主要区别包括:React使用单向数据流和state/props来管理组件状态,而Vue使用双向数据流和data/computed/methods;React推荐使用函数组件和Hooks来组织代码,Vue则推荐使用选项API或Composition API;React使用Redux作为主要的第三方状态管理库,Vue则有自己的Vuex库。
项目中配置文件
注:这些东西在面试过程中被问到的概率很低,但作为了解看一眼有个记忆还是有必要的
1.Enlint文件是什么?
答:Enlint是一个JavaScript代码风格检查工具,可以帮助开发者检查代码中的语法错误、代码风格问题等。Enlint的配置文件为enlint.json,可以通过配置文件来设置检查规则和忽略某些文件或目录
2.prettier文件是什么?
答:一款代码格式化工具,可以帮助开发者自动格式化代码,使代码风格更加统一、易读。在项目中,通常会在根目录下创建一个.prettierrc
文件,用于配置Prettier的格式化规则,在项目中,通常会使用Prettier来格式化代码,并将其集成到代码编辑器或代码仓库中,以便在提交代码时自动格式化代码。
3.Husky文件是什么?
答:Husky是一个Git钩子管理工具,可以帮助我们在Git仓库中管理和执行Git钩子。在项目中,通常会使用Husky来管理Git钩子,以确保代码质量和一致性。
Husky的配置文件通常命名为.huskyrc或.huskyrc.js,它定义了Git钩子的执行命令和参数。例如,我们可以在.huskyrc文件中定义pre-commit钩子的执行命令为lint-staged,以确保在每次提交代码前都会执行代码风格检查和格式化。
Husky还可以与其他工具集成,例如lint-staged和linters,以实现更全面的代码检查和自动化流程。在项目中使用Husky可以提高代码质量和开发效率,是一个非常有用的工具
4.Commitlint文件是什么?
答:是一个用于规范Git提交信息的工具,它可以帮助团队规范化提交信息的格式,从而提高代码的可读性和可维护性。在项目中,通常会在根目录下创建一个.commitlintrc.js
或.commitlintrc.json
文件,用于配置Commitlint的规则。
5.Commitlint文件是什么?
答:是一个用于规范Git提交信息的工具,它可以帮助团队规范化提交信息的格式,从而提高代码的可读性和可维护性。在项目中,通常会在根目录下创建一个.commitlintrc.js
或.commitlintrc.json
文件,用于配置Commitlint的规则。
6.preinstall文件是什么?
答:preinstall文件是一个在安装软件之前运行的脚本文件,它可以用来执行一些预安装操作,例如检查系统环境、安装依赖项、创建目录等。在项目中,preinstall文件通常用于在安装依赖项之前执行一些操作,以确保依赖项安装成功。preinstall文件通常被放置在项目根目录下的“scripts”文件夹中,并在package.json文件中的“scripts”字段中定义。在运行“npm install”命令时,npm会自动执行preinstall文件中的命令。
6.svg文件是什么?
答:SVG(Scalable Vector Graphics)是一种基于XML的矢量图形格式,它可以在不失真的情况下缩放和调整大小。在项目中使用SVG文件可以使图像在不同分辨率和屏幕尺寸下保持清晰度和清晰度,而不会失真或模糊。
在项目中,SVG文件可以用于图标、图形和其他矢量图形的展示。它们可以通过HTML、CSS和JavaScript进行操作和控制,使它们更加交互和动态。
6.Sass文件是什么?
答:Sass(Syntactically Awesome Style Sheets)是一种CSS预处理器,它可以让开发者使用类似编程语言的方式编写CSS代码,包括变量、函数、嵌套、继承等功能,从而提高CSS代码的可维护性和可读性。
在项目中,通常会将Sass文件(.scss或.sass扩展名)放在一个单独的文件夹中,例如“sass”或“styles”。这些文件可以包含全局的样式规则、变量、混合器和函数等,也可以包含特定页面或组件的样式规则。
为了将Sass文件编译成浏览器可识别的CSS文件,需要使用Sass编译器。常见的编译方式包括使用命令行工具、使用构建工具(如Webpack、Gulp等)或使用集成开发环境(如VS Code、WebStorm等)中的插件。编译后的CSS文件可以直接引用到HTML文件中,以应用样式规则。。
Webpack
Webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler)。它可以将项目中的多个模块(如JavaScript、CSS、图片等)打包成一个或多个优化后的文件,以便在浏览器中高效地加载和运行。Webpack通过分析项目的依赖关系,将这些依赖关系转换为一个或多个优化后的文件,这些文件可以直接在浏览器中运行。
Webpack的主要特点包括:
-
模块化:Webpack支持CommonJS、AMD、ES6等多种模块化规范,可以将项目中的代码组织成模块,提高代码的可维护性和可复用性。
-
插件系统:Webpack具有丰富的插件系统,可以通过插件来扩展Webpack的功能,例如压缩、合并、优化等。
-
加载器:Webpack通过加载器(loader)来处理非JavaScript文件,例如CSS、图片、字体等。加载器可以将这些文件转换为JavaScript模块,以便在浏览器中运行。
-
代码分割:Webpack支持代码分割,可以将项目中的代码分割成多个文件,以便在浏览器中按需加载。
-
热更新:Webpack支持热更新,可以在不刷新页面的情况下更新项目中的代码,提高开发效率。
-
请解释Webpack的核心概念,如入口、输出、加载器、插件等。
-
入口(entry):指定Webpack开始构建的起点模块。
-
输出(output):指定Webpack打包后的文件输出的路径和文件名。
-
加载器(loader):用于处理非JavaScript文件,将它们转换为JavaScript模块。
-
插件(plugin):用于扩展Webpack的功能,可以在构建过程中执行各种任务。
-
请解释Webpack的模块解析机制。
-
Webpack通过模块解析机制来查找和处理项目中的依赖关系。模块解析机制包括解析模块路径、解析模块别名、解析文件扩展名等。
-
请解释Webpack的代码分割和懒加载。
-
代码分割:将项目中的代码分割成多个文件,以便在浏览器中按需加载。代码分割可以通过配置多个入口或使用
import()
语法实现。 -
懒加载:在需要的时候才加载代码,以提高页面加载速度。懒加载可以通过
import()
语法实现。 -
请解释Webpack的热更新(Hot Module Replacement, HMR)。
-
热更新是一种在不刷新页面的情况下更新项目中的代码的技术。Webpack通过HMR插件实现热更新,可以在开发过程中实时查看代码更改的效果。
-
请解释Webpack的构建过程。
-
Webpack的构建过程包括以下几个阶段:初始化、解析、转换、打包、输出。在这个过程中,Webpack会分析项目的依赖关系,将这些依赖关系转换为一个或多个优化后的文件。
-
请解释Webpack的性能优化策略。
-
Webpack的性能优化策略包括:使用
DllPlugin
进行动态链接库优化、使用SplitChunksPlugin
进行代码分割优化、使用UglifyJsPlugin
进行代码压缩优化、使用cache-loader
进行缓存优化等。 -
请解释Webpack的兼容性问题。
-
Webpack的兼容性问题主要包括:不同浏览器对JavaScript语法的支持程度不同、不同浏览器对CSS样式的支持程度不同、不同浏览器对HTML标签和属性的支持程度不同等。为了解决这些问题,我们可以使用Babel、PostCSS等工具将代码转换为兼容性更好的代码。
-
请解释Webpack的优势和局限性。
-
Webpack的优势包括:模块化、插件系统、加载器、代码分割、热更新等。
-
Webpack的局限性包括:学习成本较高、配置复杂、构建速度较慢等。
14.Webpack的基本功能有哪些?
- 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等 文件优化:压缩
JavaScript、CSS、HTML 代码,压缩合并图片等 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载
模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件 自动刷新:监听本地源代码的变化,自动构建,刷新浏览器
代码校验:在代码被提交到仓库前需要检测代码是否符合规范,以及单元测试是否通过
自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
微前端
1.说说你对微前端的理解
微前端(Micro
Frontend)是一种前端架构风格,它的核心思想是将一个大型的前端应用拆分成一系列小型的、独立的前端应用,这些小型应用可以独立开发、部署和运行。每个小型应用都有自己的
UI、业务逻辑和后端服务,它们可以通过一定的方式(如 Web
Components、iframe、单实例应用等)集成到一个主应用(或称为基座应用)中。 微前端架构的主要优势如下:
- 模块化:微前端将大型应用拆分成小型应用,每个应用负责特定的功能或业务模块。这有助于提高代码的可读性和可维护性,降低开发难度。
- 独立开发:每个小型应用可以由独立的团队进行开发,团队成员可以根据自己的专长和兴趣选择任务,提高开发效率。
- 独立部署:由于每个小型应用都是独立的,它们可以独立部署和更新,不会影响到其他应用。这有助于提高部署的灵活性和速度。
- 技术栈自由:在微前端架构中,每个小型应用可以选择最适合自己的技术栈,如 React、Vue、Angular 等。这有助于充分发挥团队的技术优势,提高开发效果。
- 可扩展性:微前端架构具有良好的可扩展性,可以方便地将新的小型应用集成到主应用中,以满足不断变化的业务需求。
然而,微前端架构也存在一些挑战和痛点,如应用间的通信、状态管理、性能优化等。为了解决这些问题,开发者可以使用一些微前端框架(如
MicroApp、Qiankun 等)来简化开发过程和提高开发效率。
2.微前端为什么采用 microapp,qiankun 有了解过吗,qiankun 和 microapp 的区别和痛点?
MicroApp 和 Qiankun 都是微前端框架,它们旨在解决大规模企业级 Web 应用开发中的协作和可维护性问题。尽管它们的目标相似,但它们在实现方式和核心概念上有所不同。
MicroApp 的核心思想是使用 Web Components 技术构建类 WebComponent 的组件,从而实现微前端的组件化渲染。它不需要子应用修改渲染逻辑或暴露特定方法,也不需要修改 webpack 配置。MicroApp
将所有功能封装到一个类 WebComponent 组件中,从而实现在基座应用中嵌入一行代码即可渲染一个微前端应用。同时,它还提供了 js
沙箱、样式隔离、元素隔离、预加载、数据通信、静态资源补全和插件系统等一系列完善的功能。Qiankun 则采用了不同的方法。它基于 single-spa 进行封装,需要子应用修改渲染逻辑并暴露出三个方法:bootstrap、mount 和
unmount。这些方法分别对应初始化、渲染和卸载。Qiankun 还需要修改 webpack 配置以支持微前端。MicroApp 和 Qiankun 的区别和痛点如下:
- 技术栈:MicroApp 使用 Web Components,而 Qiankun 使用 single-spa。这意味着 Qiankun 需要子应用修改渲染逻辑并暴露特定方法,而 MicroApp 则不需要。
- 接入成本:MicroApp 的接入成本相对较低,因为它不需要修改子应用的渲染逻辑或暴露方法,也不需要修改 webpack 配置。Qiankun 的接入成本相对较高,因为它需要子应用进行特定的修改。
- 通信机制:MicroApp 使用数据绑定通信,每个 micro-app 元素只能与自己指向的子应用进行通信。Qiankun 则使用消息传递进行通信,这可能会增加开发和维护的复杂性。
- 性能:MicroApp 使用 Web Components,这可能会带来更好的性能优化。Qiankun 则使用 single-spa,性能方面可能会有所妥协。
总之,MicroApp 和 Qiankun 都是微前端框架,它们在实现方式和核心概念上有所不同。MicroApp 使用 Web
Components 技术,接入成本相对较低,而 Qiankun 则基于
single-spa,需要子应用进行特定的修改。在选择微前端框架时,需要根据项目需求和团队技能进行权衡。
Electron
什么是Electron?
Electron是一个使用JavaScript, HTML和CSS构建跨平台桌面应用程序的框架。它允许开发者使用Web技术快速构建具有原生感觉的应用程序。
主要特点:
跨平台: 支持Windows、macOS和Linux。
原生功能: 可以访问本地系统API,实现如文件系统、通知、菜单等原生功能。
基于Chromium和Node.js: 利用Chromium渲染引擎提供高性能的UI,结合Node.js提供强大的后端能力。
工作原理:
每个Electron应用都包含两个进程:主进程(Main process)和渲染进程(Renderer process)。
主进程负责创建窗口和管理应用的生命周期。
渲染进程负责渲染每个窗口中的内容,与Web页面类似。
核心模块:
app: 控制应用的生命周期。
BrowserWindow: 创建和管理浏览器窗口。
ipcMain和ipcRenderer: 主进程和渲染进程之间的通信。
webContents: 控制网页的加载、导航和交互。