前端面试题目汇总

315 阅读33分钟

学习教程:

CSS

参考链接:juejin.cn/post/709868…

2. CSS 百分比计算

  • 对于 width 和 height 属性,百分比是相对于其父元素的宽度和高度来计算的;
  • 对于 padding 和 margin 属性,百分比是相对于其父元素的宽度来计算的;
  • 对于 position 属性中的 top、right、bottom、left 属性,百分比是相对于其包含块(containing block)的宽度和高度来计算的;
  • 对于 font-size 属性,百分比是相对于其父元素的字体大小来计算的。

需要注意的是,如果父元素没有显式地设置宽度或高度,则它们将自适应其内容,并且百分比将相对于未确定的大小计算。此外,请不要将百分比用于一些 CSS 属性,例如 background-position,它们没有相对于其父元素的特定属性来计算的机制。

1. px 、em和 rem

📢 参考回答:

px全称pixel像素,是相对于屏幕分辨率而言的,它是一个绝对单位,但同时具有一定的相对性。因为在同一个设备上每个像素代表的物理长度是固定不变的,这点表现的是绝对性。但是在不同的设备之间每个设备像素所代表的物理长度是可以变化的,这点表现的是相对性

em是一个相对长度单位,具体的大小需要相对于父元素计算,比如父元素的字体大小为80px,那么子元素1em就表示大小和父元素一样为80px,0.5em就表示字体大小是父元素的一半为40px

rem是根元素字体的单位,比如 html{font-size:16px;} ,1rem相当于16px。

2. vw、vh 是什么?

📢 参考回答:

vwvhCSS3 新单位,即 view width 可视窗口宽度 和 view height 可视窗口高度。1vw 就等于可视窗口宽度的百分之一,1vh 就等于可视窗口高度的百分之一。

3.  介绍下 BFC 及其应用

📢 参考回答:

所谓 BFC—— 块格式化上下文(Block Formatting Context),指的是一个独立的布局环境,BFC 内部的元素布局与外部互不影响。

触发 BFC 的方式有很多,常见的有:

  • 根元素,即html
  • 设置浮动,float的值不为none(默认)
  • overflow 设置为 auto、scroll、hidden,不为visible(默认)
  • positon 设置为 absolute、fixed

常见的 BFC 应用有:

  • 解决浮动元素令父元素高度坍塌的问题
  • 解决非浮动元素被浮动元素覆盖问题
  • 解决外边距垂直方向重合的问题

4. 介绍下 BFC、IFC、GFCFFC

📢 参考回答:

  • BFC:块级格式上下文,指的是一个独立的布局环境,BFC 内部的元素布局与外部互不影响。
  • IFC:行内格式化上下文,将一块区域以行内元素的形式来格式化。
  • GFC:网格布局格式化上下文,将一块区域以 grid 网格的形式来格式化
  • FFC:弹性格式化上下文,将一块区域以弹性盒的形式来格式化

5. flex 布局如何使用?

Flex 布局教程:语法篇 - 阮一峰的网络日志 (ruanyifeng.com)

📢 参考回答:

flex 是 Flexible Box 的缩写,意为"弹性布局"。指定容器display: flex即可。

容器有以下属性:flex-direction,flex-wrap,flex-flow,justify-content,align-items,align-content。

  • flex-direction属性决定主轴的方向;flex-direction: row | row-reverse | column | column-reverse
  • flex-wrap属性定义,如果一条轴线排不下,如何换行; flex-wrap: nowrap | wrap | wrap-reverse
  • flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap;
  • justify-content属性定义了项目在主轴上的对齐方式。justify-content:flex-start(默认值) | flex-end | center | space-between | space-around
    • space-between: 两端对齐,项目之间的间隔相等
    • space-around:每个项目两侧的间隔相等
  • align-items属性定义项目在交叉轴上如何对齐。align-items:flex-start | flex-end | center | baseline | stretch (默认)
  • align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。align-content:flex-start | flex-end | center | space-between | space-around | stretch(默认)

项目有以下6个属性

  • order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
  • flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
  • flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
  • flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。
  • flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
  • align-self 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖 align-items 属性。默认值为 auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

flex:1表示 flex: 1 1 auto,项目平分容器里的空间;

flex还有两种写法 initial (0 1 auto) 和 none (0 0 auto)

grid布局

最强大的 CSS 布局 —— Grid 布局

以下代码生成一个两行三列的布局

.wrapper {
  margin: 60px;
  /* 声明一个容器 */
  display: grid;
  /*  声明列的宽度  */
  grid-template-columns: repeat(3, 200px);
  /*  声明行间距和列间距  */
  grid-gap: 20px;
  /*  声明行的高度  */
  grid-template-rows: 100px 200px;
}
.one {
  background: #19CAAD;
}
.two { 
  background: #8CC7B5;
}
.three {
  background: #D1BA74;
}
.four {
  background: #BEE7E9;
}
.five {
  background: #E6CEAC;
}
.six {
  background: #ECAD9E;
}
.item {
  text-align: center;
  font-size: 200%;
  color: #fff;
}

6. 分析比较 opacity: 0、visibility: hidden、display: none 优劣和适用场景。

📢 参考回答:

  • 结构: display:none: 会让元素完全从渲染树中消失,渲染的时候不占据任何空间, 不能点击, visibility: hidden:不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,不能点击 opacity: 0: 不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,可以点击
  • 继承: display: none和opacity: 0:是非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示。 visibility: hidden:是继承属性,子孙节点消失由于继承了hidden,通过设置visibility: visible;可以让子孙节点显式。
  • 性能: displaynone : 修改元素会造成文档回流,读屏器不会读取display: none元素内容,性能消耗较大 visibility:hidden: 修改元素只会造成本元素的重绘,性能消耗较少读屏器读取visibility: hidden元素内容 opacity: 0 : 修改元素会造成重绘,性能消耗较少

7. 如何用 cssjs 实现多行文本溢出省略效果,考虑兼容性 (去哪儿面试题)

📢 参考回答:

CSS 实现方式

单行文本溢出后显示省略号:


overflow: hidden; // 超出宽度隐藏
text-overflow:ellipsis; // 显示为省略号
white-space: nowrap;//不换行,强制在一行中显示所有内容

多行:


display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; //行数
overflow: hidden;

CSS3中-moz-或-webkit-是什么意思?-CSDN博客

CSS3中新增了一些属性,例如box-reduis、box-orient、text-overflow等等,而这些属性在以往的版本中是不存在的,或者不被支持的,因此,针对不同的浏览器,规定其内核名称让它们可以对这些新增属性进行解析。

css3中的display:-webkit-box的用法 - 极客分享 (geek-share.com)

兼容:

p{position: relative; line-height: 20px; max-height: 40px;overflow: hidden;}
p::after{content: "..."; position: absolute; bottom: 0; right: 0; padding-left: 40px;
background: -webkit-linear-gradient(left, transparent, #fff 55%);
background: -o-linear-gradient(right, transparent, #fff 55%);
background: -moz-linear-gradient(right, transparent, #fff 55%);
background: linear-gradient(to right, transparent, #fff 55%);
}

JS 实现方式:

  • 使用split + 正则表达式将单词与单个文字切割出来存入words
  • 加上 '...'
  • 判断scrollHeight与clientHeight,超出的话就从words中pop一个出来

8. 居中为什么要使用 transform(为什么不使用 marginLeft/Top)(阿里)

📢 参考回答:

transform 属于合成属性(composite property),对合成属性进行 transition/animation 动画将会创建一个合成层(composite layer),这使得被动画元素在一个独立的层中进行动画。通常情况下,浏览器会将一个层的内容先绘制进一个位图中,然后再作为纹理(texture)上传到 GPU,只要该层的内容不发生改变,就没必要进行重绘(repaint),浏览器会通过重新复合(recomposite)来形成一个新的帧。

top/left属于布局属性,该属性的变化会导致重排(回流)(reflow/relayout),所谓重排即指对这些节点以及受这些节点影响的其它节点,进行CSS计算->布局->重绘过程,浏览器需要为整个层进行重绘并重新上传到 GPU,造成了极大的性能开销。

9. 介绍下粘性布局(sticky)(网易)

📢 参考回答:

position 中的 sticky 值是 CSS3 新增的,设置了 sticky 值后,在屏幕范围(viewport)时该元素的位置并不受到定位影响(设置是top、left等属性无效),当该元素的位置将要移出偏移范围时,定位又会变成fixed,根据设置的left、top等属性成固定位置的效果。

sticky 属性值有以下几个特点:

  • 该元素并不脱离文档流,仍然保留元素原本在文档流中的位置。
  • 当元素在容器中被滚动超过指定的偏移值时,元素在容器内固定在指定位置。亦即如果你设置了top: 50px,那么在sticky元素到达距离相对定位的元素顶部50px的位置时固定,不再向上移动。
  • 元素固定的相对偏移是相对于离它最近的具有滚动框的祖先元素,如果祖先元素都不可以滚动,那么是相对于viewport来计算元素的偏移量

10. 说出 space-betweenspace-around 的区别?(携程)

📢 参考回答:

这个是 flex 布局的内容,其实就是一个边距的区别,按水平布局来说,space-between是两端对齐,在左右两侧没有边距,而space-around是每个 子项目左右方向的 margin 相等,所以两个item中间的间距会比较大。

11. CSS3transitionanimation 的属性分别有哪些(哔哩哔哩)

📢 参考回答:

transition 过渡动画:

  • transition-property:指定过渡的 CSS 属性
  • transition-duration:指定过渡所需的完成时间
  • transition-timing-function:指定过渡函数
  • transition-delay:指定过渡的延迟时间

animation 关键帧动画:

  • animation-name:指定要绑定到选择器的关键帧的名称
  • animation-duration:动画指定需要多少秒或毫秒完成
  • animation-timing-function:设置动画将如何完成一个周期
  • animation-delay:设置动画在启动前的延迟间隔
  • animation-iteration-count:定义动画的播放次数
  • animation-direction:指定是否应该轮流反向播放动画
  • animation-fill-mode:规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式
  • animation-play-state:指定动画是否正在运行或已暂停

12. 分析比较 opacity: 0、visibility: hidden、display: none 优劣和适用场景

📢 参考回答:

  1. display: none (不占空间,不能点击)(场景,显示出原来这里不存在的结构)
  2. visibility: hidden(占据空间,不能点击)(场景:显示不会导致页面结构发生变动,不会撑开)
  3. opacity: 0(占据空间,可以点击)(场景:可以跟transition搭配)

13. 讲一下png8、png16、png32的区别,并简单讲讲 png 的压缩原理

📢 参考回答:

PNG图片主要有三个类型,分别为 PNG 8/ PNG 24 / PNG 32。

  • PNG 8:PNG 8中的8,其实指的是8bits,相当于用2^8(2的8次方)大小来存储一张图片的颜色种类,2^8等于256,也就是说PNG 8能存储256种颜色,一张图片如果颜色种类很少,将它设置成PNG 8得图片类型是非常适合的。
  • PNG 24:PNG 24中的24,相当于3乘以8 等于 24,就是用三个8bits分别去表示 R(红)、G(绿)、B(蓝)。R(0-255),G(0-255),B(0-255),可以表达256乘以256乘以256=16777216种颜色的图片,这样PNG 24就能比PNG 8表示色彩更丰富的图片。但是所占用的空间相对就更大了。
  • PNG 32:PNG 32中的32,相当于PNG 24 加上 8bits的透明颜色通道,就相当于R(红)、G(绿)、B(蓝)、A(透明)。R(0255),G(0255),B(0255),A(0255)。比PNG 24多了一个A(透明),也就是说PNG 32能表示跟PNG 24一样多的色彩,并且还支持256种透明的颜色,能表示更加丰富的图片颜色类型。

PNG图片的压缩,分两个阶段:

  • 预解析(Prediction):这个阶段就是对png图片进行一个预处理,处理后让它更方便后续的压缩。
  • 压缩(Compression):执行Deflate压缩,该算法结合了 LZ77 算法和 Huffman 算法对图片进行编码。

14. 如何用 CSS 实现一个三角形

📢 参考回答:

可以利用 border 属性

利用盒模型的 border 属性上下左右边框交界处会呈现出平滑的斜线这个特点,通过设置不同的上下左右边框宽度或者颜色即可得到三角形或者梯形。

如果想实现其中的任一个三角形,把其他方向上的 border-color 都设置成透明即可。

示例代码如下:

html
复制代码
<div></div>
css
复制代码
div{
width: 0;
height: 0;
border: 10px solid red;
border-top-color: transparent;
border-left-color: transparent;
border-right-color: transparent;
}

15. 如何实现一个自适应的正方形

📢 参考回答:

方法1:利用 CSS3 的 vw 单位

vw 会把视口的宽度平均分为 100 份

css
复制代码
.square {
 width: 10vw;
 height: 10vw;
 background: red;
}

方法2:利用 margin 或者 padding 的百分比计算是参照父元素的 width 属性

.square {
 width: 10%;
 padding-bottom: 10%; 
 height: 0; // 防止内容撑开多余的高度
 background: red;
}

16. 清除浮动的方法

📢 参考回答:

  • clear 清除浮动(添加空div法)在浮动元素下方添加空div,并给该元素写css样式: {clear:both;height:0;overflow:hidden;}
  • 给浮动元素父级设置高度
  • 父级同时浮动(需要给父级同级元素添加浮动)
  • 父级设置成inline-block,其margin: 0 auto居中方式失效
  • 给父级添加overflow:hidden 清除浮动方法
  • 万能清除法 ::after 伪元素清浮动(现在主流方法,推荐使用)

17. 说说两种盒模型以及区别

📢 参考回答:

盒模型也称为框模型,就是从盒子顶部俯视所得的一张平面图,用于描述元素所占用的空间。它有两种盒模型,W3C盒模型和IE盒模型(IE6以下,不包括IE6以及怪异模式下的IE5.5+)

理论上两者的主要区别是二者的盒子宽高是否包括元素的边框和内边距。当用CSS给给某个元素定义高或宽时,IE盒模型中内容的宽或高将会包含内边距和边框,而W3C盒模型并不会。

18. 如何触发重排和重绘?

📢 参考回答:

任何改变用来构建渲染树的信息都会导致一次重排或重绘:

  • 添加、删除、更新DOM节点
  • 通过display: none隐藏一个DOM节点-触发重排和重绘
  • 通过visibility: hidden隐藏一个DOM节点-只触发重绘,因为没有几何变化
  • 移动或者给页面中的DOM节点添加动画
  • 添加一个样式表,调整样式属性
  • 用户行为,例如调整窗口大小,改变字号,或者滚动。

19. 浏览器渲染的过程

理解 Web 的重排和重绘_性能优化, 性能, performance, 会员专栏 教程_W3cplus

  1. 首先解析 HTML 代码,将其所有转化成 DOM 树
  • 每一个 HTML 标签对应一个 节点(Node)
  • HTML 标签(元素)的内容则被转换成 文本节点(Text Node)
  • 树形的根部(Root Node)则是 documentElement (<html>元素)
  1. 碰到 <link rel="stylesheet"> 或 <style> 开始处理 CSS 样式表,会将 CSS 样式表解析成 CSSOM 树
  • 浏览器遇到自己不认识的前缀定义的样式规则,会直接被忽略

  • 样式信息层层递进,即层叠规则

    • 浏览器都有自己的默认样式 User Agent 样式
    • 用户设置样式
    • 开发者编写的样式
  1. DOM 和 CSSOM 结合在一起,构建一个渲染树(Render Tree)
  • 渲染树有点像 DOM 树,但并不完全匹配
  • 渲染树了解样式
  • 可能有一些DOM元素在渲染树中有不止一个节点
  • 渲染树中的一个节点被称为一个帧(Frame),也称为盒子(Box,对应的就是 CSS 盒模型)
  • 每个节点都有 CSS 盒模型的属性
  1. 渲染树构建完成,浏览器就可以在屏幕上绘制(画出)渲染树的节点
image.png

19. 重绘与重排的区别?

📢 参考回答:

重排(回流): 部分渲染树(或者整个渲染树)需要重新分析并且节点尺寸需要重新计算,表现为重新生成布局,重新排列元素

重绘: 由于节点的几何属性发生改变或者由于样式发生改变,例如改变元素背景色时,屏幕上的部分内容需要更新,表现为某些元素的外观被改变

单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制受到此次重排影响的部分

重排和重绘代价是高昂的,它们会破坏用户体验,并且让UI展示非常迟缓,而相比之下重排的性能影响更大,在两者无法避免的情况下,一般我们宁可选择代价更小的重绘。

『重绘』不一定会出现『重排』,『重排』必然会出现『重绘』。

20. 如何优化图片

📢 参考回答:

  1. 对于很多装饰类图片,尽量不用图片,因为这类修饰图片完全可以用 CSS 去代替。
  2. 对于移动端来说,屏幕宽度就那么点,完全没有必要去加载原图浪费带宽。一般图片都用 CDN 加载,可以计算出适配屏幕的宽度,然后去请求相应裁剪好的图片。
  3. 小图使用 base64 格式
  4. 将多个图标文件整合到一张图片中(雪碧图)
  5. 选择正确的图片格式:
  • 对于能够显示 WebP 格式的浏览器尽量使用 WebP 格式。因为 WebP 格式具有更好的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量,缺点就是兼容性并不好
  • 小图使用 PNG,其实对于大部分图标这类图片,完全可以使用 SVG 代替
  • 照片使用 JPEG

21. 你能描述一下渐进增强和优雅降级之间的不同吗?

📢 参考回答:

渐进增强 (progressive enhancement) :针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

优雅降级 (graceful degradation) :一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

区别:优雅降级是从复杂的现状开始,并试图减少用户体验的供给,而渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。

22. CSS3 新增了那些东西?

📢 参考回答:

CSS3 新增东西众多,这里列举出一些关键的新增内容:

  • 选择器
  • 盒子模型属性:border-radius、box-shadow、border-image
  • 背景:background-size、background-origin、background-clip
  • 文本效果:text-shadow、word-wrap
  • 颜色:新增 RGBA,HSLA 模式
  • 渐变:线性渐变、径向渐变
  • 字体: @font-face
  • 2D/3D转换:transform、transform-origin
  • 过渡与动画:transition、@keyframes、animation
  • 多列布局
  • 媒体查询

23. 隐藏页面中的某个元素的方法有哪些?

📢 参考回答:

隐藏类型

屏幕并不是唯一的输出机制,比如说屏幕上看不见的元素(隐藏的元素),其中一些依然能够被读屏软件阅读出来(因为读屏软件依赖于可访问性树来阐述)。为了消除它们之间的歧义,我们将其归为三大类:

  • 完全隐藏:元素从渲染树中消失,不占据空间。
  • 视觉上的隐藏:屏幕中不可见,占据空间。
  • 语义上的隐藏:读屏软件不可读,但正常占据空。

完全隐藏

(1) display 属性

css
复制代码
 display: none;

(2) hidden 属性 HTML5 新增属性,相当于 display: none

html
复制代码
<div hidden></div>

视觉上的隐藏

(1) 设置 posoition 为 absolute 或 fixed,通过设置 top、left 等值,将其移出可视区域。

css
复制代码
position:absolute;
left: -99999px;

(2) 设置 position 为 relative,通过设置 top、left 等值,将其移出可视区域。

css
复制代码
position: relative;
left: -99999px;
height: 0

(3) 设置 margin 值,将其移出可视区域范围(可视区域占位)。

js
复制代码
margin-left: -99999px;
height: 0;

语义上隐藏

aria-hidden 属性

读屏软件不可读,占据空间,可见。

js
复制代码
<div aria-hidden="true"></div>

JavaScript

1. JavaScript 实现对上传图片的压缩

HTML5 file API加canvas实现图片前端JS压缩并上传

读取用户上传的 File 对象,读写到画布(canvas)上,利用 Canvas 的 API 进行压缩,完成压缩之后再转成 File(Blob) 对象,上传到远程图片服务器;不过有时候我们也需要将一个 base64 字符串压缩之后再变为 base64 字符串传入到远程数据库或者再转成 File(Blob) 对象。

2.谈一谈 JavaScript 的异步

JS的异步是采用单线程非阻塞式的方式来实现的,JS的单线程并不是指整个JS引擎只有1个线程。它是指运行代码只有1个线程,但是它还有其他线程来执行其他任务。比如时间函数的计时、AJAX技术中的和后台交互等操作。

因此,异步操作的步骤应该为:JS引擎中执行代码的线程开始运行代码,当执行到异步方法时,把异步的回调方法放入到队列中,然后由专门计时的线程开始计时。代码线程继续运行。如果计时的时间已到,那么它会通知代码线程来执行队列中对应的回调函数。当然,前提是代码线程已经把同步代码执行完后。否则需要继续等待,就像这个例子中一样。

查看该链接里的异步解释 :前端JavaScript从入门到精通学习笔记(WebAPI)

setTimeout(() => {
  console.log(1);
}, 0);

new Promise((resolve, reject) => {
  console.log(2);
  resolve('p1');
  new Promise((resolve, reject) => {
    console.log(3);

    setTimeout(() => {
      resolve('setTimeout2');

      console.log(4);
    }, 0);

    resolve('p2');
  }).then((data) => {
    console.log(data);
  });

  setTimeout(() => {
    resolve('setTimeout1');

    console.log(5);
  }, 0);
}).then((data) => {
  console.log(data);
});

console.log(6);

3.浏览器和 nodejs 事件循环

浏览器与Node的事件循环(Event Loop)有何区别? - 知乎 (zhihu.com)

image.png

4. 原型链、Function与Object

原型是什么

原型的概念:每一个javascript对象(除null外)创建的时候,就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型中“继承”属性

所有的东西都由Object衍生而来,即所有东西原型链的终点指向Object.prototype

Function与Object

首先,要明确一点,JS中所有的函数都是Function的实例。要注意的一点是,Function自身能够生成自身,即Function的原型就是Function。

对原型、原型链、 Function、Object 的理解 - 知乎 (zhihu.com)

  1. 当 new 一个函数的时候会创建一个对象,『函数.prototype』 等于 『被创建对象._proto_』
  2. 一切函数都是由 Function 这个函数创建的,所以『Function.prototype === 被创建的函数._proto_』
  3. 一切函数的原型对象都是由 Object 这个函数创建的,所以『Object.prototype === 一切函数.prototype.proto
  4. Function.prototype._proto_ === Object.prototype.
  5. Function.prototype.constructor === Function.

image.png

function People(){}
var p = new People()
p.__proto__ === People.prototype 
People.__proto__ === Function.prototype
People.prototype.__proto__ === Object.prototype

image.png

5.JS中的new操作符做了什么

new操作符首先生成一个对象,将该对象的proto属性指向构造函数或自定义对象的prototype,接着将构造函数或自定义对象的this指向该实例对象,如果构造函数返回一个对象,则使用构造函数返回的对象,如果返回的不是对象则使用该实例对象

image.png

function Car (price) { 
    this.price = price 
    return { km: 200 } 
} 
let bigCar = new Car(90) 
console.log(bigCar.price, bigCar.km) // undefined, 200

new的代码

function Person(name){
    this.name = name
}
function mynew(func, ...args){
    let obj = Object.create(func.prototype)// Object.create() 方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
    let res = func.apply(obj, args)
    return res instanceof Object? res: obj
}
let p = mynew(Person, 'aa')
console.log(p) //Person {name: "aa"}

6.JS数组的forEach方法可以使用break、contine吗

JavaScript 如何跳出(终止)forEach 循环 (zhihu.com)

在forEach中,不能使用 continue 和 break ,可以使用 return 或 return false 跳出循环,效果与 for 中 continue 一样,但是该方法无法一次结束所有循环。

如果直接使用 continue 或者 break 还会报错,如下所示:

[1,2,3].forEach(()=>{
    break;
})
// SyntaxError: Illegal break statement 即解释器无法确定break出去之后的位置。
[1,2,3].forEach(()=>{
    continue;
})
// SyntaxError: Illegal continue statement: no surrounding iteration statement 即语句并不在迭代语句内,不知道下一次循环在哪。

除了抛出异常以外,没有办法中止或跳出 forEach() 循环。如果你需要中止或跳出循环,forEach() 方法不是应当使用的工具。

7. null和undefined的变量会占用内存吗

undefined代表定义了声明了一个变量名但是没有给这个变量赋值,(但它在后台内存中占据了一定的空间)

null表示一个变量定义了并且也赋值了 只是值为null(在js内存后台内存中不占据空间,js性能更优化)

8. map和weakMap有什么区别

map

  • Map默认情况下不包含任何键,所有键都是自己添加进去的。不同于Object原型链上有一些默认的键。

  • Map的键可以是任何类型数据,就连函数都可以。

  • Map的键值对个数可以轻易通过size属性获取,Object需要手动计算。

  • Map在频繁增删键值对的场景下性能比Object更好。

WeakMap

WeakMap是ES6中新增的一种集合类型,叫做'弱映射'。它和Map是兄弟关系,与Map的区别在于这个弱字,API还是Map那套API

  • WeakMap只能将对象作为键名
  • WeakMap的键名引用的对象是弱引用,指不能确保其引用的对象不会被垃圾回收器回收的引用
  • 不可遍历。正因为WeakMap对键名引用的对象是弱引用关系 ,因此WeakMap内部成员是会取决于垃圾回收机制有没有执行,运行前后成员个数很可能是不一样的,而垃圾回收机制的执行又是不可预测的,因此不可遍历。

Map和WeakMap区别

  • Map的键可以是任意类型,WeakMap只接受对象作为键,不接受其它类型的值作为键
  • Map的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键;WeakMap的键是弱引用,键所指向的对象是可以被垃圾回收,此时键是无效的。
  • Map可以被遍历,WeakMap不能被遍历

9. 如何判断一个对象为空对象

JavaScript判断空对象的5+1种方式 - 掘金 (juejin.cn)

  • JSON.stringify(data) === '{}'
  • Object.keys(data).length
  • Object.values(data).length
  • 使用for in
    let data = {};
    let data1 = {
        name: "大帅哥",
        age: "18"
    }
    let _fn = (obj) => {
        for (let key in obj) {
            return false;
        }
        return true
    }
    console.log(_fn(data)) //true
    console.log(_fn(data1)) //false

Vue

1.Vue的$route和$router的区别

routeroute和router的区别

$route是一个跳转的路由对象,每一个路由都会有一个$route对象,是一个局部的对象,可以获取对应的name,path,params,query等

$router是VueRouter的一个对象,通过Vue.use(VueRouter)和 Vue构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由,包含了许多关键的对象和属性。 以history对象来举例:

$router.push({path:'home'}),本质是向history栈中添加一个路由,在我们看来是切换路由,但本质是在添加一个history记录

$router.replace({path:'home'}),//替换路由,没有历史记录

$router.push('/login') ,跳转到指定路由

2.Vue的指令有哪些

Vue基本指令(超详细介绍)_vue add()和clear()方法-CSDN博客

v-bind 单向绑定数据,只能数据改变,视图改变,可以简写为:
v-model 双向绑定数据,只能用于表单元素上,绑定的是value
v-on v-on指令用于给页面元素绑定事件,可以简写为@,还有许多事件修饰符:

  • .stop :阻止事件冒泡到父元素
  • .prevent:阻止默认事件发生
  • .capture:使用事件捕获模式
  • .self:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
  • .once:只执行一次

v-text 将数据输出到元素内部,如果输出的数据有HTML代码,会作为普通文本输出
v-html 将数据输出到元素内部,如果输出的数据有HTML代码,会被渲染 v-for遍历数据语法:v-for="(item,index) in items"

  • items:要遍历的数组,需要在vue的data中定义好。
  • item:迭代得到的数组元素的别名 v-if,条件判断。当得到结果为true时,所在的元素才会被渲染。 语法:v-if="布尔表达式"
    v-show 也是用于根据条件展示元素的选项指令,用法大致一样,但是v-show是通过设置display:none来实现的,无论是否显示都会创建该元素。

React

1.Hooks有什么限制

为什么React Hooks会有两条使用规则

  • 不要在循环、条件或嵌套函数中调用 Hook;
  • 在 React 的函数组件中调用 Hook。

2.React

手写算法

1.手写 Promise 或者 Promise 的静态方法

面试官:“你能手写一个 Promise 吗” - 知乎 (zhihu.com)

以下代码为手写Promise类,且实现了异步处理,promise.then()方法比较复杂,需要处理多种情况

const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';

class Promise {
  constructor(exectuor){
    this.status = PENDING;
    this.value = undefined;
    this.reason = undefined;
    // 存放成功的回调
    this.onResolvedCallbacks = [];
    // 存放失败的回调
    this.onRejectedCallbacks= [];

    let resolve = (value) => {
      if(this.status === PENDING){
        this.status = FULFILLED
        this.value = value
        this.onResolvedCallbacks.forEach(fn=>fn());
      }
    }
    let reject = (reason) => {
      if(this.status === PENDING){
        this.status = REJECTED
        this.reason = reason
        this.onRejectedCallbacks.forEach(fn=>fn())
      }
    }

    try{
      exectuor(resolve, reject)
    }catch(error){
      reject(error)
    }
  }

  then(onFulfilled, onRejected){
    if(this.status === FULFILLED){
      onFulfilled(this.value)
    }
    if(this.status === REJECTED){
      onRejected(this.reason)
    }
    if(this.status === PENDING){
      this.onResolvedCallbacks.push(()=>{
        onFulfilled(this.value)
      })
      this.onRejectedCallbacks.push(()=>{
        onRejected(this.value)
      })
    }
  }
}

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功');
  },1000);
}).then(
  (data) => {
    console.log('success', data)
  },
  (err) => {
    console.log('faild', err)
  }
)

2. 手写节流与防抖

查看该文章中的防抖与节流章节 JS从入门到精通课程学习笔记——JavaScript 进阶

防抖

  1. 单位时间内频繁触发事件,只执行最后一次
  2. 使用场景:
  • 搜索框搜索输入,只需用户最后一次输入完,再发送请求
  • 手机号、邮箱验证输入检测
// 防抖函数 
function debounce(fn, t) { 
    let timeId 
    return function () { //必须要返回一个定时函数,这样才能多次执行 
    // 如果有定时器就清除 
    if (timeId) clearTimeout(timeId) 
    // 开启定时器
    timeId = setTimeout(function () { 
            fn() 
        }, t) 
   }
} 

节流

  1. 单位时间内频繁触发事件,只执行一次
  2. 使用场景: 高频事件,页面尺寸缩放 resize ,鼠标移动, 滚动条滚动等
function throttle(fn, t){
    let timeid= null
    return function(){
        if(!timeid){
            timeId = setTimeout( function(){ 
                fn() 
                timeId = null // 在定时器结束后清空定时器,即设置为null
1.
            }, t)
        }
    }
}

计算机基础

1. 进程与线程

进程是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,计算机系统资源的基本单位。线程有自己的资源,如内存、cpu、io等

线程是进程的一个执行单元,是进程内的调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。线程共享本进程的资源如内存、I/O、cpu等,不利于资源的管理和保护,而进程之间的资源是独立的,能很好的进行资源管理和保护。

浏览器

客户端渲染与服务端渲染优缺点

简述服务器端渲染、客户端渲染、静态站点生成 - 知乎 (zhihu.com)

服务器端渲染(SSR)的优点

  • 更快的首屏加载:这一点在慢网速或者运行缓慢的设备上尤为重要。服务端渲染的 HTML 无需等到所有的 JavaScript 都下载并执行完成之后才显示,所以用户将会更快地看到完整渲染的页面。除此之外,数据获取过程在首次访问时在服务端完成,相比于从客户端获取,可能有更快的数据库连接。这通常可以带来更高的核心 Web 指标评分、更好的用户体验,而对于那些首屏加载速度与转化率直接相关的应用来说,这点可能至关重要。
  • 统一的心智模型:可以使用相同的语言以及相同的声明式、面向组件的心智模型来开发整个应用,而不需要在后端模板系统和前端框架之间来回切换。
  • SEO更友好:搜索引擎爬虫可以直接看到完全渲染的页面。

服务器端渲染(SSR)的缺点

服务器端脚本要求服务器为每个请求提供预加载的 HTML 页面。特别在客户端不断向 Web 服务器发送更多请求以向用户提供新的、修改过的信息时服务器容量的负载就会很重。因此,SSR 不适合请求量大或需要大量用户交互的网站,在此类项目中,Web 服务器的响应时间会抵消优化页面加载速度的优势。

客户端渲染(CSR)的优点

客户端渲染(CSR)被证明是一种有利可图的方法,特别是对于具有大量用户交互的 Web 项目。如果网站最初加载速度较慢,则后续页面的渲染速度会更快。用户体验明显优于服务器端渲染,因为用户每次访问新页面时不必立即完全加载所有脚本和内容。

由于脚本是在用户的浏览器中执行的,因此与服务器端脚本不同,可以被查看源代码,通常涉及加密等安全性的功能就不太适合客户端来实现,。

客户端渲染(CSR)的缺点

对客户端脚本的关注伴随着两个关键问题。首先,搜索引擎很难对页面进行抓取和索引。谷歌的爬虫能够做到这一点,即使 SEO 条件不是最佳的 - 特别是因为许多其他搜索引擎通常根本无法索引客户端呈现的页面。

另一方面,客户端脚本需要浏览器支持 JavaScript。基本上就是这种情况 - 但由于弹出窗口和跟踪工具也基于 CSR,并且客户端脚本也会影响加载时间,因此有各种浏览器扩展程序会阻止脚本。

亚信


1.数组转为字符串,字符串转为数组

join()方法可以把数组转换为字符串,不过它可以指定分隔符。在调用 join() 方法时,可以传递一个参数作为分隔符来连接每个元素。如果省略参数,默认使用逗号作为分隔符,这时与 toString() 方法转换操作效果相同。

split()方法可以把字符串转换为数组

2.JSON 与 数组、字符串的转换

  • json对象转字符串
var json = {"name":"iphone","price":666}; //创建对象;
var jsonStr = JSON.stringify(json);  
console.log(jsonStr); //"{"name":"iphone","price":666}"
//数组转json串
var arr = [1,2,3, { a : 1 } ];
JSON.stringify( arr );//"[1,2,3,{"a":1}]"
  • 字符串转为数组
//json字符串转数组
var jsonStr = '[1,2,3,{"a":1}]';
var jsarr=JSON.parse( jsonStr );
alert(jsarr); //(4) [1, 2, 3, {…}]
0: 1
1: 2
2: 3
3: {a: 1} 
  • 字符串转为JSON对象
var jsonString = '{"bar":"property","baz":3}';
var jsObject = JSON.parse(jsonString);    //转换为json对象
alert(jsObject);  //{bar: "property", baz: 3}

3.date对象的方法

www.runoob.com/jsref/jsref…
date对象中的各种方法:

  • getFullYear() 从 Date 对象以四位数字返回年份。
  • getHours() 返回 Date 对象的小时 (0 ~ 23)。
  • getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。
  • getMonth() 从 Date 对象返回月份 (0 ~ 11)。

4.vue的生命周期函数

  • beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
  • created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板
  • beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
  • mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示
    运行期间的生命周期函数:
  • beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
  • updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
    销毁期间的生命周期函数:
  • beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
  • destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

京东


js中垃圾回收的两种方式
www.cnblogs.com/shytong/p/4…

参考链接: 百度面经