新版前端高频面试题

目录:

一、移动web

  • 面试要有条理性的回答:
  • 多用以下词汇以利于事半功倍
    • 原因…所以…最后
    • 首先…其次…最后

1.1 请说下初始化CSS样式的意义


1、浏览器差异:因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面显示差异。

2、提高编码质量:初始化CSS可以节约网页代码,节约网页下载时间;还会使得我们开发网页内容时更加方便简洁,不用考虑很多。如果不初始化,整个页面做完会很糟糕,重复的css样式很多。
常见写法
①:最简单的初始化方法就是: * {padding: 0; margin: 0;} 。这样一个通用符在编写代码的时候是快,但这样写的话,他会把所有的标签都初始化一遍,这样就增加了网站运行的负载,会使网站加载过慢。
②:最好的做法是针对常用的标签进行初始化即可。
参考淘宝、腾讯等网站的css初始化:https://www.jb51.cc/css/1113842.html

1.2 谈谈你对HTML语义化的理解?

答:
根据页面的结构,选择合适的语义化标签,用正确的标签做正确的布局,同时有利于浏览器、搜索引擎的解析。

追问:为什么要语义化
1、HTML语义化让页面的内容结构化,结构更清晰,便于让浏览器、搜索引擎解析
2、即使在没有样式CSS情况下也以一种文档格式显示,并且是易于阅读的
3、搜索引擎也依赖于HTML标记来确定上下文和各个关键字的权重,利于SEO
4、使阅读源代码的人更容易将网站分块,便于阅读维护理解

追问:平时你写HTML代码还有那些注意事项?
1)尽可能少的使用无语义的标签div和span
2)在语义不明显时,既可以使用div或者p时,尽量用p,因为p在默认情况下有上下间距,对兼容特殊终端有利
3)不要使用纯样式标签,如:b、font、u等,改用CSS设置
4)需要强调的文本,可以包含在strong或者em标签中(浏览器预设样式,能用css指定就不用他们),strong默认样式是加粗(不要用b),em是斜体(不用i)
5)使用表格时,标题要用caption,表头用thead,主体部分用tbody包围,尾部用tfoot包围。表头和单元格要区分开,表头用th,单元格用td
6)表单域要用fieldset标签抱起来,并用legend标签说明表单的用途
7)每个input标签对应的说明文本都需要使用label标签,并且通过为input设置id属性,在label标签中设置for=someId来让说明文本和相对应的input关联起来

追问:你知道有哪些HTML5新增的语义标签?
article(定义文章)aside(定义文章的侧边栏)、figure(一组媒体对象以及文字)、figurecaption(定义figure的标题)、footer(定义页脚)、header(定义页眉)、nav(定义导航栏)、section(定义文档中的区段)、time(定义日期和时间)、dialog(定义一个对话框)

1.3 请说下如何居中一个div?

答: 方法有很多,我大概记得以下5~6种吧。(回答可以直接说标题即可 如果非要说代码,也是说文字)
方法一: 利用定位

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .parent {
      width: 500px;
      height: 500px;
      border: 1px solid #000;
      position: relative;
    }

    .child {
      width: 100px;
      height: 100px;
      border: 1px solid #999;
      position: absolute;
      top: 50%;
      left: 50%;
      margin-top: -50px;
      margin-left: -50px;
    }
  </style>
</head>

<body>
  <div class="parent">
    <div class="child">我是子元素</div>
  </div>
</body>

</html>

方法二:利用 margin:auto;

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .parent {
      width: 500px;
      height: 500px;
      border: 1px solid #000;
      position: relative;
    }

    .child {
      width: 100px;
      height: 100px;
      border: 1px solid #999;
      position: absolute;
      margin: auto;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
    }
  </style>
</head>

<body>
  <div class="parent">
    <div class="child">我是子元素</div>
  </div>
</body>

</html>

方法三: 利用 display:table-cell

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .parent {
      width: 500px;
      height: 500px;
      border: 1px solid #000;
      display: table-cell;
      vertical-align: middle;
      text-align: center;
    }

    .c hild {
      width: 100px;
      height: 100px;
      border: 1px solid #999;
      display: inline-block;
    }
  </style>
</head>

<body>
  <div class="parent">
    <div class="child">我是子元素</div>
  </div>
</body>

</html>

方法四: 利用 display: flex;设置垂直水平都居中

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .parent {
      width: 500px;
      height: 500px;
      border: 1px solid #000;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .c hild {
      width: 100px;
      height: 100px;
      border: 1px solid #999;
    }
  </style>
</head>

<body>
  <div class="parent">
    <div class="child">我是子元素</div>
  </div>
</body>

</html>

方法五: 计算父盒子与子盒子的空间距离(这跟方法一是一个道理) (不够好:自己算)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .parent {
      width: 500px;
      height: 500px;
      border: 1px solid #000;
    }

    .c hild {
      width: 100px;
      height: 100px;
      border: 1px solid #999;
      margin-top: 200px;
      margin-left: 200px;
    }
  </style>
</head>

<body>
  <div class="parent">
    <div class="child">我是子元素</div>
  </div>
</body>

</html>

方法六: 利用 transform

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .parent {
      width: 500px;
      height: 500px;
      border: 1px solid #000;
      position: relative;
    }

    .c hild {
      width: 100px;
      height: 100px;
      border: 1px solid #999;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
  </style>
</head>

<body>
  <div class="parent">
    <div class="child">我是子元素</div>
  </div>
</body>

</html>

1.4 请说下px/em/rem这三个单位有什么区别?

答:
①: px 是绝对单位,而 em 和 rem 是相对单位。
②: em相对于当前元素内文本的字体大小,找不到就找父亲的文字大小,而 rem是相对的HTML 根元素文字大小
③: px适合于固定文字大小, em经常用于比如段落首行缩进等, rem在后期移动端开发经常用于做适配。

1.5 你说下rem布局的原理和思路吧?

答:
1、rem 是css的相对单位,rem缩放是相对根元素字体大小.
2、rem 布局的本质是等比缩放,一般是基于宽度。
3、rem 会配合媒体查询(或js动态获取屏幕宽度)来一起使用,来实现屏幕的适配。

rem布局实现目的: 等比缩放

1、元素所有属性 只要px单位—>rem单位

2、rem单位非常神奇,背后 基准值会变。

3、基准值取决于根元素字号大小,屏幕变化导致根元素字号大小变;

4、实现原理:给window注册resize。当变化内部函数设置 根元素字号大小 = 为当前屏幕宽度 / 固定数值 通常为10

1.6 通过CSS如何写一个三角形?

答:
利用css边框属性就可以得到三角形。
边框是梯形的,如果盒子没有宽高,则会变成三角形,设置三个角透明色,其中一个角给颜色,就能得到三角形了

1.7 如何实现两侧固定中间自适应的布局?

答:
圣杯布局

最简单方法,可以通过flex布局来显示, 大盒子里面包含左中右三个小盒子,父盒子利用display:flex。两侧直接写固定宽度,中间盒子给flex:1 即可。

传统方案:父亲设置 box-sizing:border-box CSS3盒子模型,设置左右padding, 子元素三个:左右侧绝对定位宽度(正好是设置padding)高度同父亲 。 中间:设置100%宽 100%高

1.8 你知道BFC吗?

答:
①:BFC(Block Formatting Context),即块级格式化上下文,它是页面中的一块渲染区域,并且有一套属于自己的渲染规则,BFC目的是形成一个相对于外界完全独立的空间,让内部的子元素不会影响到外部的元素
②:触发BFC的条件

  • 根元素,即HTML元素
  • 浮动元素:float值为left、right
  • overflow值不为 visible,为 auto、scroll、hidden
  • display的值为inline-block、inltable-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid
  • position的值为absolute或fixed

③:BFC的主要使用场景:

  • 防止margin重叠(塌陷)。 比如给父级添加overflow,就触发了BFC, 还有子元素浮动,不会触发外边距塌陷原因也是因为触发了BFC
  • 清除内部浮动。 同样,清除浮动方法中有个overflow:hidden 方法

1.9、CSS选择器的优先级

!important > 行内样式>ID选择器 > 类选择器 > 标签 > 通配符 > 继承 

1.10、HTML5新特性

1. 语义化标签: header nav section article aside footer
2. 多媒体标签: video audio
3. input类型: number search email tel date file time  url
4. 本地离线存储 localStorage 长期存储数据,改变浏览器数据不会丢失
			  sessionStorage 浏览器关闭数据会丢失
5. 自定义属性 data-*
6. 画布 Canvas
7. webscoket 双向通信协议

1.11、CSS3新特性

1. 圆角 border-radius
2. 盒子模型 box-sizing
3. 阴影 box-shadow 盒子阴影  text-shadow 文字阴影
4. 过渡 transition
5. 2D转换transform  translate(平移) scale(缩放)  skew(斜切) rotate(旋转) transform-origin 控制转换中心点
6. 3D转换 perspective(透视距)  transform-style(3D控件效果)
7. 渐变 linear-gradient radial-gradient
8. 弹性布局 flex
9. 媒体查询 @media screen and () {...}
10. 边框图片 border-image
11. 自定义动画 @keyframes    animation
12. 颜色 新增RGBA HSLA模式
13. 背景 background-size   background-origin   background-clip

1.12、CSS的盒子模型

1、有两种, IE 盒子模型、标准盒模型;
2IE盒模型设置的宽为:整个盒子所占有的宽度。(内容的宽+左右padding+左右border)
3、标准盒模型就是内容区域的宽。
可以通过box-sizing 属性来设置他们:
	● content-box 是默认值。盒子的实际大小为:content +  padding  +  border 相加后的值
	● border-box:设置的边框和内边距的值是包含在 width 内的。也就是说,如果你将一个元素的
	 width 设为 100px,那么这 100px 会包含它的 border 和 padding,内容区的实际宽度是
	  width 减去 (border + padding) 的值。

1.13、移动端适配方案都有哪些

1. 响应式布局: Bootstrap,腾讯全端等网站采用这个方法:
	主要是利用媒体查询,根据不同的页面宽度进行不同的样式设置

2. rem + flexible.js: 手机淘宝团队采用这个方法
	rem单位回根据html的font-size大小进行转变的单位 1rem = html的font-size大小
	flexible.js 能够动态的获取当前设备视口宽度,给html标签设置font-size,因此能够实现移动适配

3. vw / vmin :哔哩哔哩
	vw是一个视口单位,是指相对于视口的宽度;视口会被均分为100份,其中1vw等于视口宽度的1%,
	比如浏览器的宽度为1920px,则“1vw=1920px/100=19.2px”。  
    该方案解决了rem 需要依赖不同html的font-size尺寸的问题,他相对于当前设备的视口宽高来进行变化。
    - vw:相对于视口的宽度, 视口被均分为 100 单位的vw,1vw等于视口宽度的1%- vh: 相对于视口的宽度, 视口被均分为 100 单位的vh,1vh等于视口高度的1%- vmin:选取vw和vh中最小的那个。
    - vmax:选取vw和vh中最大的那个。

4. flex布局:天猫的实现方式进行说明:
	利用弹性盒子的特点宽度自适应,高度定死,元素采用px做单位。随着屏幕宽度宽度发生变化,
	页面也会跟着变化,这里因为高度是不会随着设备的变化发生改变的,所以并不是完整的移动端适配,
	效果就和PC页面的流式布局差不多

1.14、说出space-between和space-around的区别?(携程)

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

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

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

1.16、 居中为什么要使用 transform(为什么不使用 margin-left/margin-top)(阿里)

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

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

1.17、介绍下粘性布局(sticky)(网易)

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

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

1.18、图片下方空白缝隙的解决方案

产生空白缝隙原因:因为行内和行内块对齐方式问题,图片默认和文字的基线对齐,所以会出现底部缝隙。
解决方法:
	1. 修改图片显示模式,除行内和行内块显示模式
	2. 给图片设置vertical-align: 除baseline以外的值
	3. 设置父元素文字大小为 0

1.19、如何实现两栏布局

1. 利用margin和浮动
	左侧盒子左浮动,浮动后脱标,右侧盒子设置margin-left,值就是左侧盒子的宽度
2. 利用flex布局
	父级开启flex布局,左侧盒子设置固定宽度,右侧盒子可以设置flex:1;
3. 利用绝对定位
	利用绝对定位,将父级元素设置为相对定位。
	左边元素设置为absolute定位,并且固定宽度设置为200px,left值设置为0。
	将右边元素的left值设置为左边固定宽度200px,right值设置为0

1.20、前端页面有哪三层构成,分别是什么?作用是什么?

web标准有三部分组成:结构html、表示css、行为 javascript
1、结构层:由 HTML 标记语言负责创建,仅负责语义的表达。解决了页面“内容是什么”的问题。

2、表示层:由CSS负责创建,解决了页面“如何显示内容”的问题。

3、行为层:由脚本(js)负责。解决了页面上“内容应该如何对事件作出反应”的问题

二、JS基础

2.1 说下typeof返回的数据类型

回答:
①:简单数据类型直接返回对应的英文,比如:number string boolean undefined 等,特殊情况,null 返回 object
②:复杂数据类型返回 object,函数返回的是 function fn(){…} typeof fn

2.2 请说下转换为false的情况有哪些?

答:
七种
自动转换为false的有: 0 、 “”、 null、 false、 NaN、 undefined、还有不成立的表达式

2.3 两个等号和三个等号的区别是什么?

回答
== 表示是相等,只比较内容,类型不同,会隐式转换为同类型,进行比较。
=== 表示是全等,不仅比较内容,也比较类型。如果类型不同,直接false

2.4 请说说你对作用域链的理解?

回答
①:JavaScript中的作用域分为全局作用域、局部作用域,多个嵌套的作用域形成作用域链。
②:作用域链:内部寻找一个变量的查找规则,

  • 规则:
    • 当在某个作用域中查找变量时,如果当前作用域没有找到,则向上层作用域查找,上层没有声明,继续向上层查找,一直找到全局作用域。
    • 找的过程中,找到则使用该变量,没有找到则报错。

2.5 简单数据类型与复杂数据类型在内存上存储有什么区别?

回答:
①:基本类型(简单类型)主要为以下6种:Number、String、Boolean、Undefined、null、symbol

  • 基本数据类型的值存储在 栈中

②:引用类型(复杂类型) Object、Array、Function

  • 引用类型的值存储于 堆中

三、webapi

3.1 请说下什么是重绘和重排(回流)?他们的区别是什么?

回答:
重排: 也叫做回流,当DOM元素影响了元素的几何属性(例如宽和高),浏览器需要重新计算元素的几何属性,同样其它元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为“重排”。
重绘: 完成重排后,浏览器会重新绘制受影响的部分到屏幕上中,该过程称为“重绘”。
总结:
当我们改变DOM的大小,增加删除都会导致重排,当给DOM元素改变颜色的时候,会导致重绘,重排一定会重绘,重绘不会重排。重排会影响性能,所以我们尽快能的减少重排的操作(这句话是重点)
追问:

1问:那么如何触发重排和重绘?
	任何改变用来构建渲染树的信息都会导致一次重排或重绘:
	添加、删除、更新DOM节点
	通过display: none隐藏一个DOM节点-触发重排和重绘
	通过visibility: hidden隐藏一个DOM节点-只触发重绘,因为没有几何变化
	移动或者给页面中的DOM节点添加动画
	添加一个样式表,调整样式属性
	用户行为,例如调整窗口大小,改变字号,或者滚动。
2问:重绘与重排的区别?
	重排:  部分渲染树(或者整个渲染树)需要重新分析并且节点尺寸需要重新计算,表现为重新生成布局,重新排列元素
	
	重绘:  由于节点的几何属性发生改变或者由于样式发生改变,例如改变元素背景色时,屏幕上的部分内容需要更新,表现为某些元素的外观被改变
    单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制受到此次重排影响的部分
	
	重排和重绘代价是高昂的,它们会破坏用户体验,并且让UI展示非常迟缓,而相比之下重排的性能影响更大,在两者无法避免的情况下,一般我们宁可选择代价更小的重绘。

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

3.2 说说this的指向问题吧?

回答: 谁调用执行谁。

this是个关键字,它的指向和函数的调用方式有关, 初步的理解就是,this指向所在函数的调用者。
1、 以函数形式调用时, this 永远都是 window
2、 以方法的形式调用时, this 是调用方法的对象

let obj = {
   fn:function(){
      log(this)
   }
}
obj.fn();  // this--->obj

3、 以构造函数的形式调用时, this 是新创建的那个对象
4、 使用 call 和 apply 调用时, this 是指定的那个对象
5、 箭头函数: 箭头函数的 this 按照普通变量对待。比如把他当做 x 变量即可,然后按照作用域链找就行了。
6、全局中的this是window
7、事件处理函数,如果是普通的function函数,则this指向事件源。

3.3 事件流分为哪两个阶段?

事件流是指事件传播的顺序,由事件捕获 => 目标事件 => 事件冒泡
所以事件流分为捕获和冒泡两个阶段。

3.4 事件委托的实现原理?如果获取当前触发的dom节点?

回答:
①:事件委托主要利用事件冒泡特性来实现的。
②:事件委托(事件委派)主要有2个使用场景:

  • 如果有多个子元素,可以把事件注册给父元素,因为点击子元素,也会将事件冒泡到其父元素上,利用这个特点提高了性能。
  • 给后来动态生成的元素绑定事件。因为动态生成的元素没有办法直接绑定事件,可以利用事件委托来绑定事件。

使用 e.target 获取当前触发事件的元素。

3.5 你能说说怎么理解事件循环机制的?

回答:
1、JavaScript 是一门单线程语言. 单线程可能会出现阻塞的情况,所js分了同步任务和异步任务。
2、同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入 任务队列。
3、主线程内的任务执行完毕为空,会去 任务队列 读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)。

四、JS高级

4.1、什么是深/浅拷贝

浅拷贝: 拷贝对象的一层属性,如果对象里面还有对象,拷贝的是地址, 两者之间修改会有影响,适用于对象里面属性的值是简单数据类型的.
深拷贝: 拷贝对象的多层属性,如果对象里面还有对象,会继续拷贝,使用递归去实现.

4.2、如何用递归实现深拷贝?

function copy(oldD) {
    let newD  // 新数据
    // 需要判断oldD 何方数据类型?
    // ************************************数组
    if(oldD instanceof Array){
      newD = []
      for (let i = 0; i < oldD.length; i++) {
        let val = oldD[i]  // 每一项数据
        val = copy(val) // val
        newD.push(val)
      }
    }
    // ***********************************对象
    else if(oldD instanceof Object){
      newD = {}
      for (let key in oldD) {
        let val = oldD[key]  // 每一项数据,有可能又是简单数组
        val = copy(val)  // val不能直接赋值,需要经过copy
        newD[key] = val  // 添加键值对
      }
    }
    
    // ***********************************简单数据
    else {
      newD = oldD
    }
    return newD 
  }

其他方式:
lodash:_.cloneDeep(被拷贝的对象)
JSON.parse(JSON.stringify(被拷贝的对象))

4.3、描述下垃圾回收机制?

首先:垃圾回收机制内部算法:引用计数 和 标记清除
接下来:
● 引用计数:把堆上对象能够访问次数记下来,如果发现某个对象计数为0,算法认为没有变量访问这个对象。该对象所占空间,判定是垃圾,进行回收。但是:如果两个对象相互引用,各自计数永远不会为0,不会判定为是垃圾,不会回收。所以:主流浏览器不再使用该算法。
● 标记清除:核心就是 从 使用对象次数 到 无法到达对象;只要是堆上对象无法访问,哪怕是对象相互引用,但是无法访问,算法对该对象标记为垃圾空间。

4.4、对闭包是怎么理解的?

答:
● 基本形式:两个嵌套关系的函数,内部函数可以访问外部函数定义的局部变量,那么该变量与内部函数就构造了闭包的形式
● 优点:形成私有空间,避免全局变量的污染
● 缺点:持久化内存,导致内存泄露
● 解决:
○ 1、尽快避免函数的嵌套,以及变量的引用
○ 2、执行完的变量,可以赋值null,触发垃圾回收机制,进行回收释放内存

4.5、什么是原型对象和原型链

答:
原型对象:每个构造函数都有prototype属性,这个属性的值是个对象,称之为原型对象。
原型链:对象都有__proto__属性,这个属性指向它的原型对象,原型对象也是对象,也有__proto__属性,指向原型对象的原型对象,这样一层一层形成的链式结构称为原型链.

4.6、原型链有什么意义?

总得来说:给实例化对象上调用方法或使用某个属性,提供查询机制。
具体查询:
先在实例化对象本身上去找该方法。
如果没有,去实例化对象的__proto__(原型对象上去找)
如果当前原型对象上还没有该方法,继续往原型对象上的原型对象上去找
如果还是没有找到,报错 对象.xxx is not function

4.7、call、apply和bind的区别

答:
1、call和apply方法都可以调用函数,方法内的第一个参数可以修改this的指向
2、call方法可以有多个参数,除了第一个参数,其他参数作为实参传递给函数;apply方法最多有2个参数,第二个参数是个数组或伪数组,数组里面的每一项作为实参传递给函数
3. bind方法不能调用函数,它会创建一个副本函数,并且该新函数的this指向已经被改变。

4.8、怎么理解函数的防抖和节流

防抖:就是指触发事件后,在n秒后对应的函数会执行。如果在n秒中又触发了事件,则会重新计算函数执行时间。
节流:就是指连续触发事件,如果上一次触发的对应的执行函数没有执行完成,下一次触发是不会引起对应代码执行的

4.9、关键字new的执行过程?

1、在函数内部创建空对象{}
2、this变量 此时本次调用中 代表当前对象
3、this.属性名 相当于往 对象 添加属性名
4、随着调用传入实参,实参添加到对应属性名上属性值
5、把对象return出来

五、ajax

5.1、请说出宏任务与微任务,在事件循环机制中是如何执行的?

答:
1、代码:分为【宏任务】与【微任务代码】
【宏任务】:主代码块、定时器代码、dom节点事件触发代码、ajax代码 ;(主代码块: script标签包着这些代码)
【微任务】 promise实例对象的.then(回调函数)
2、宏任务与微任务都会去【宿主环境】。
3、这些代码里面回调函数到了要执行点的时候,不是直接去【主线程】,而是去【任务队列】。到了【任务队列】分为两个队列【宏任务队列】与【微任务队列】
4、最一开始【事件循环机制】先执行 【主代码块】,又会分为:
异步代码:在执行的过程中又分出来【宏任务】与【微任务】到【宿主环境】,然后各自排队到任务队列里的【宏任务队列】与【微任务队列】
同步代码:分到主线程上,就继续执行。
5、执行完第一个主代码里面同步代码后,【事件循环机制】会先把【微任务队列】里面所有函数执行完成后,才去执行【宏任务队列】的下一个的函数。

简叙:任务队列里执行函数【微任务队列】比【宏任务队列】优先。

例题:(答案博主就不发了,可以通过运行代码知道答案,或者私聊博主)

例题1:

<script>
    console.log(1);
    setTimeout(() => {
        console.log(2);
    }, 0)
    console.log(3);
</script>
<script>
    console.log(4);
    setTimeout(() => {
        console.log(5);
    }, 0)
    console.log(6);
</script>

例题2:

 console.log(1)

  setTimeout(function() {
    console.log(2)
  }, 0)

  const p = new Promise((resolve, reject) => {
    console.log(3)
    resolve(1000) // 标记为成功
    console.log(4)
  })

  p.then(data => {
    console.log(data)
  })

  console.log(5)

例题三:

new Promise((resolve, reject) => {
    resolve(1)

    new Promise((resolve, reject) => {
      resolve(2)
    }).then(data => {
      console.log(data)
    })

  }).then(data => {
    console.log(data)
  })

  console.log(3)

例题四:

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)

例题五:

<script>
    console.log(1);
    async function fnOne() {
      console.log(2);
      await fnTwo(); // 右结合先执行右侧的代码, 然后等待
      console.log(3);
    }
    async function fnTwo() {
      console.log(4);
    }
    fnOne();
    setTimeout(() => {
      console.log(5);
    }, 2000);
    let p = new Promise((resolve, reject) => { // new Promise()里的函数体会马上执行所有代码
      console.log(6);
      resolve();
      console.log(7);
    })
    setTimeout(() => {
      console.log(8)
    }, 0)
    p.then(() => {
      console.log(9);
    })
    console.log(10);
  </script>
 <script>
    console.log(11);
    setTimeout(() => {
      console.log(12);
      let p = new Promise((resolve) => {
        resolve(13);
      })
      p.then(res => {
        console.log(res);
      })
      console.log(15);
    }, 0)
    console.log(14);
  </script>

例题六:

<script>
    console.log(1);
    async function fnOne() {
      console.log(2);
      await fnTwo(); // 右结合先执行右侧的代码, 然后等待
      console.log(3);
    }
    async function fnTwo() {
      console.log(4);
    }
    fnOne();
    setTimeout(() => {
      console.log(5);
    }, 2000);
    let p = new Promise((resolve, reject) => { // new Promise()里的函数体会马上执行所有代码
      console.log(6);
      resolve();
      console.log(7);
    })
    setTimeout(() => {
      console.log(8)
    }, 0)
    p.then(() => {
      console.log(9);
    })
    console.log(10);
  </script>
 <script>
    console.log(11);
    setTimeout(() => {
      console.log(12);
      let p = new Promise((resolve) => {
        resolve(13);
      })
      p.then(res => {
        console.log(res);
      })
      console.log(15);
    }, 0)
    console.log(14);
  </script>

5.2、http和https的区别

答:
1.https协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。
2.http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl/tls加密传输协议。
3.http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4.http的连接很简单,是无状态的;HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

5.3、get 和post的区别

答:
get

  1. 在url后面拼接参数,只能以文本的形式传递数据
  2. 传递的数据量小,4KB左右
  3. 安全性低, 会将数据显示在地址栏
  4. 速度快,通常用于安全性要求不高的请求
  5. 会缓存数据

post

  1. 安全性比较高
  2. 传递数据量大,请求对数据长度没有要求
  3. 请求不会被缓存,也不会保留在浏览器历史记录里

5.4、在地址栏输入网址,到数据返回的过程是什么?

  1. 输入url地址后,首先进行DNS解析,将相应的域名解析为IP地址。
  2. 根据IP地址去寻找相应的服务器。
  3. 与服务器进行TCP的三次握手,建立连接。
  4. 客户端发送请求,找到相应的资源库。
  5. 客户端拿到数据,进行相应的渲染。

5.5、怎么理解三次握手

答:
第一次握手:建立连接时,客户端发送syn包到服务器,等待服务器确认。
第二次握手:服务器收到syn包,必须确认客户的SYN,同时自己也发送一个SYN包(syn=y)到客户端
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK,此包发送完毕,客户端和服务器进入(TCP连接成功)状态,完成三次握手

通俗:
第一次:客户端告诉服务器,我有个诉求,想要向你请求数据,你能听见么?
第二次:服务器告诉客户端,收到你的诉求,允许请求数据,你能听见么?
第三次:客户端告诉服务器,OK收到。

6、怎么理解四次挥手
答:
第一次分手:客户端向服务器发送一个FIN报文段;此时,客户端进入FIN_WAIT_1状态;这表示没有数据要发送给服务器了。
第二次分手:服务器 收到 客户端 发送的FIN报文段,向 客户端 回一个ACK报文段,主机1进入FIN_WAIT_2状态;服务器告诉 客户端,我知道你的诉求了,也“同意”你的关闭请求,但是具体什么时候关闭,等我通知;
第三次分手:服务器 向 客户端 发送FIN报文段,说可以正式关闭连接了,同时 服务器 进入LAST_ACK状态。
第四次分手:客户端 收到 服务器 发送的FIN报文段,向 服务器 发送ACK报文段,然后 客户端 进入TIME_WAIT状态;服务器 收到 客户端的ACK报文段以后,服务器就正式关闭连接;此时,客户端等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,客户端也可以正式关闭连接了。

通俗:
第一次分手:客户端告诉服务器,我有个诉求,我这边没有数据了,我要准备关闭了。
第二次分手:服务器收到信息后,回复:我收到你的诉求了,你可以进行准备着,但是何时正式关闭,等我通知。
第三次分手:服务器 给 客户端发信:你现在准备正式关闭了。
第四次分手:客户端 给 服务器发信:OK呢,我知道了。
(服务器:收到信息后,服务器正式关闭了)
(客户端:???等了一会,这家伙没有说就下线了,嗯~真的关了,好吧,我也是正式关了。)

(持续更新中~~,家人们关注博主不迷路,向创作优质内容而努力,注:以上全是自己的整理,如有错误请联系博主)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小祥编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值