每天一道前端基础面试题

340 阅读19分钟

所有的努力不会白费,区别是它带来的效果来得早一点或者晚一点!!

希望你自己可以坚持下去!!

本人前端小白,如果有错误,欢迎各位批评指正!

-------------------------------------------------

延迟加载JS有哪些方式?

我们一般可以把JS写在文档的末端达到延迟加载的效果,但通常在script标签前面添加async和defer,二者区别如下:

defer:先等html全部解析完成,再按照顺序执行JS脚本。

async:async是和html同步解析的,它不是按照顺序执行JS代码,通常是谁先加载完,谁先执行,对于一些有顺序要求的JS脚本要注意使用。

JS数据类型有哪些?

共有七种数据类型,分为基本数据类型(其余六个)和引用类型(Object)

记忆口诀:USONB  (you are so niu bi)

U: undefined

S: string, symbol (ES6)

O: object

N: null, number

B: boolean

提示:好像还有个bigint , 本人目前学习程度较浅,此题先不考虑。

注意一些数据类型的考题:

Console.log(true+1) //2

true在计算中会被默认转换成1,false会被默认转换为0。

Console.log(true+‘name’) //truename

Console.log(NaN+‘name’) //NaNname

字符串与其他类型相加,均会被转换为连接形式的字符串

Console.log(undefined+1) //NaN

Console.log(typeof NaN) //Number

NaN的数据类型为number,它不是一个具体的数字,好比无穷大

Console.log(typeof null) //Object

Console.log(typeof undefined) // undefined

Null与undefined的区别?

作者在一开始设计JS的时候借鉴了Java语言设计了null,但是null表示无的对象,作者觉得表示“无”这个值的最好不要是一个对象,而且null在会被隐式转换为0,不容易发现错误。

具体区别如下:null是一个表示“无”的对象(空对象指针),转换数值会变成0;而undefined属于基本数据类型,转换数值为NaN。

==与===有什么不同?

==:比较的是值

console.log( 1 == ‘1’ ) //true,string会被隐式转换成number,值一样则为true

console.log( true == 1 ) //true, boolean会被隐式转换成number

console.log( null == undefined ) //true

console.log( [1,2] == ‘1,2’ ) //true,Object会被转换为基本类型,值一样则为true

 

var s = ‘2’

if (s==2) {

  console.log( typeof s )

}  //string

因为 valueOf() 的转换,该方法通常在JavaScript后台自动调用,并不显式地出现在代码中。

如何验证你的说法?

已知:

var arr = [ 1 , 2 ]

var str = ‘ 1 , 2 ’

console.log( var == str ); // true

 

我们可以通过修改valueOf(),修改掉隐式转换,来验证

Object.prototype.valueOf = function() {

alert( 123 )

}

var arr = [ 1 , 2 ]

var str = ‘ 1 , 2 ’

console.log( var == str ); // false

 

===:除了比较值,还比较数据类型

推荐使用===,因为==会涉及到隐式转换valueOf(),可能存在坑。

JS作用域考题

原则

1.除了函数外,JS不存在块级作用域(let和const除外?)

2.作用域链:内部可以访问外部变量,但是外部无法访问内部的变量(内部有优先访问内部的,再去查找外部的)

3.声明变量的时候注意是使用var还是没有写(window.)

image.png

4.面试时注意先看本层作用域有无该变量,注意JS存在变量提升的机制(变量悬挂声明)

image.png

来练练:

①:

image.png

依次输出结果为?

image.png

如果注释掉 a函数中的 var b = 2; 呢?

image.png

②:

image.png

image.png

③:对于优先级排序:变量声明>声明普通函数>参数>变量提升

image.png

image.png

image.png

④补充:

image.png

image.png

image.png

JS的微任务与宏任务

1.      JavaScrip是一门单线程的语言,即同一时间只能做一件事,它的用途主要是与用户互动以及操作DOM,如果采用多线程,比如一个操作是在节点上添加内容,一个是删除此节点,此时浏览器不知道以哪个为准。

2.      JavaScript代码执行流程:同步任务执行完--》事件循环--》微任务--》宏任务

3.      其中进入事件循环的有:(Ajax)请求,定时器,事件(鼠标点击等)…

4.      微任务:promise.then...  

宏任务:setTimeout..

要执行宏任务,先要清空所有的微任务。

image.png

image.png

JS作用域+this指向+原型考题

image.png

image.png

image.png

image.png

JS判断数组的方法

image.png

Slice与Splice

image.png

image.png

数组去重

image.png

image.png

找出多维数组的最大值

image.png

给字符串新增方法实现功能

498debd99ee850151a6929cecb23cbd.jpg

image.png

找出字符串中出现次数最多的字符以及其出现次数

image.png

call、apply和bind的区别

image.png

闭包

image.png

image.png

image.png

原型和原型链

image.png

JS的继承方式

image.png

image.png

image.png

image.png

深拷贝与浅拷贝(手写深拷贝)

image.png

localStorage、sessionStorage与cookie

image.png

var、let和const的区别

image.png

image.png

image.png

image.png

关于对象合并

image.png

new操作符有什么功能

image.png

箭头函数与普通函数的区别

image.png

image.png

find和filter的区别

image.png

some和every的区别

image.png

防抖与节流

image.png

image.png

HTML && CSS

HTML5的新特性与语义化

语义化指的是合理正确使用语义化标签来创建页面结构【让正确的标签做正确的事】

语义化标签有:header、NavLink、main、article、section、aside、footer

语义化优点:

1.在没有css样式的情况下,页面也会呈现一定的结构效果

2.代码结构清晰,便于阅读

3.有利于开发和维护,方便不同设备渲染网页

4.有利于搜索引擎优化,搜索引擎爬虫会根据不同标签赋予不同的权重

HTML5的新特性有:

1.语义化标签

2.音视频标签,通过和标签,不再需要flash等插件

3.history API(React路由组件使用)

4.web存储数据 localStorage、sessionStorage

5.表单控件(input text、password)、calendar、date、url等

6.引入Geolocation,可以获取用户的地理位置信息。等等

CSS选择器与权重

选择器:ID选择器、类选择器/伪类选择器/属性选择器、标签选择器、通配符选择器 还包括行内样式、!important和继承

样式表的来源相同时: !important > 行内样式>ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性

权重计算

image.png

CSS盒子模型

CSS盒子模型包括W3C标准盒子模型和IE盒子模型

二者的区别在:

标准盒子模型由marginborderpaddingcontent组成
IE盒子模型由margincontentcontent+border+padding)组成

我们可以通过以下代码转换盒子模型:

box-sizingcontent-box /*标准盒子模型 初始定义的width和height值只给content部分,默认值*/
box-sizingborder-box /*IE盒子模型 内减模式,始终不会超过初始设置的width和height值*/

image.png

position属性有哪些取值?

image.png

对BFC规范的理解

image.png

水平居中、垂直居中知识点

image.png

image.png

页面布局

rem布局

rem布局方式一般是根据font-size的大小来计算,比如说手机宽度为750px,那么我们一般会设置其宽度的十分之一即75 px=1 rem,rem的核心原理是等比缩放,在不同宽度的设备上,具有相同的网页展现形式。它可以快速适用各种移动端布局,图片高度字体等,但也存在一些缺点:我们必须通过js来控制根元素的大小,这导致css样式与js代码具有一定的耦合性;同时要保证font-size代码要在css样式之前;

百分比布局

通过%单位实现使得浏览器中的组件的宽和高随着浏览器的变化而变化,实现响应式效果,除了 border-radius 外,还有比如 translate、background-size 等都是相对于自身的,height 百分比相 对于 height,padding、border、margin 等等不论是垂直方向还是水平方向,都相对于直接父元素的 width,但是如果使用百分比,相对父元素的属性并不是唯一的会造成我们使用百分比单位容易使布局问题变得复杂

flex布局

布局中比较常见的方案,它是基于盒状模型,依赖 display 属性 + position 属性 + float 属性,又分为容器属性和元素属性。

容器属性:justify-content:对齐方式,水平主轴对齐方式 
         align-items:对齐方式,竖直轴线方向
         flex-direction:决定主轴的方向(即子 item 的排列方法)
                         row | row-reverse | column | column-reverse;
        flex-wrap:决定换行规则 flex-wrap: nowrap | wrap | wrap-reverse;
元素属性:order:定义项目的排列顺序,顺序越小,排列越靠前,默认为 0
         flex0,表示该项目不会在伸缩方向上伸缩,并且将保持其原始尺寸。
                  它不会填充容器中的剩余空间,而是将保留自己的基础尺寸
         flex1,表示该项目可以在伸缩方向上伸缩,并且占据剩余的可用空间。
                  具体来说,它的伸缩比例为 1,表示它将分配到容器中剩余的所有空间

使用css画一个三角形

宽高设置为0px,核心是利用border,伪元素可用可不用

image.png

页面隐藏一个元素

1.opcity:0:该元素隐藏起来,不会改变页面布局,如果有绑定事件,仍然可以触发。

2.visibility:hidden:该元素隐藏起来,不会改变页面布局,不会触发已经绑定的事件,在文档中仍然保留原有的空间(重绘)

3.display:none:该元素隐藏起来,改变页面布局,可以直接简单理解为页面中“暂时去掉”了该元素,在文档中不保留空间(回流+重绘)

HTTP与HTTPS

概念

http:全称为超文本传输协议(Hyper Text Transfer Protocol),这是一种基于客户端——服务端架构的协议,采用TCP作为传输协议。

https:是在http的基础上增加了一个SSl/tls层进行信息加密,其目的是确保数据的安全性以及确保网站的真实性

区别和优缺点

1.http是超文本传输协议,其中一个显著的特点是传输的数据是明文的,这样无法保证信息的安全,于是通过http配合ssl/tls加密传输协议形成的https可以保证数据再传输中的隐私性和安全性

2.默认端口不同,http的默认端口是80,而https默认的端口是443

3.http的连接比较简单,是无状态的。而https在握手阶段比较费时,使得页面加载时间延长,耗电量增加

4.https需要CA证书,需要一定的费用

https工作原理

背景知识:
①任何经过A公钥加密的文件,只有A的私钥可以解密
②任何有公钥的人,可以确认信息是否被私钥加密过

1.客户端使用 https url 访问服务器,则要求 web 服务器建立 ssl/tls 链接

2.web 服务器接收到客户端的请求之后,会将网站的证书(证书中包含了公钥),传输给客户端

3.客户端和 web 服务器端开始协商 SSL 链接的安全等级,也就是加密等级

4.客户端浏览器通过双方协商一致的安全等级,开始建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站。

5.web 服务器通过自己的私钥解密出会话密钥

6.web 服务器通过会话密钥加密与客户端之间的通信

三次握手与四次挥手

三次握手:

1.客户端向服务器发送SYN包,进入SYN-SENT状态,等待服务器确认
2.服务器收到后回复SYN+ACK包,服务器进入SYN-REC状态
3.客户端收到之后,再发送一个ACK包,此时连接建立,完成三次握手

注意:三次握手的过程中不包含任何数据,要等握手完毕才开始传输数据

举个例子:

A:是B吗?我准备跟你发信息,你听得到吗?
B:可以听到,你能听到我讲话吗?
C:我也可以听到你说话!
*于是就开始了正常的交流对话过程*

65dea00786bb2c4d4ffb0f358b2e9d5.png

四次挥手:

处于连接的服务端和客户端都可以主动发起关闭连接的请求,以客户端发起请求为例子

1.客户端发送FIN包,表示要关闭连接,客户端进入终止等待1状态,这是第一次挥手
2.服务器收到FIN包后,发送一个ACK包,服务端进入关闭等待状态,客户端进入终止等待2状态,此时服务器还可以继续发送数据,客户端也还能接收数据,这是第二次挥手
3.等待服务器发完最后的数据后,服务器会发送FIN包,进入最后的确认状态,这是第三次挥手
4.客户端收到后回复ACK包,进入超时等待状态,经过超时时间后关闭连接,而服务器收到ACK包后立即关闭连接,这是第四次挥手。

服务器结束TCP的时间会比客户端要早

33e97ed6661c4f43d201fa7da75d0a2.png

举个例子:

1.A:呼叫B,我要求与你断开通话
2.B:知道了,请等一下,我还有话要说
3.B:好了,我说完了
4.A:好的,我知道了(此时B立刻下线,A在手机旁等了一会才下线)

TCP与UDP的区别

1.连接方式不同:TCP是基于连接的,而UDP基于非连接的。
  可以简单理解为:TCP是与对方通过打电话的方式:可以保证电话接通,互相通话,结束挂断;
  而UDP类似写信的方式,我们无法确认对方是否收到信件,收到的信息是否完整,收到的信件顺序是否正确等
2.传输的可靠性:TCP提供可靠的数据传输,如果出现数据包丢失的情况,会根据序列号和长度重发数据,而UDP在丢失的时候无法重发
3.UDP的简单处理方式导致性能损耗少,占用资源少;
  而TCP需要进行复杂的确认和重传机制,导致占用的资源和带宽都比较大。
4.TCP的优点是稳定可靠,通常运用于网页浏览、电子邮件、文件传输等;
  UDP的特点是传输速度快,适合实时性要求高、少量数据包丢失没有较大影响的应用,
  如语音电话、视频直播、在线游戏等

跨域

跨域是指浏览器不能访问其他网站的资源,根本原因是同源策略引起的。

同源策略指的是协议,域名,端口号都相同,只要有三个中有任意一个不相同,则会被视为跨域!

576f71aff47a8d1ad159b2b459c37de.jpg

1.JSONP(JSON with Padding),我们可以利用script标签可以从其他源请求脚本的特点,实现跨域

1.  在客户端创建一个回调函数,并指定回调函数的名称。
2.  在客户端创建一个 <script> 标签,并将该标签的 src 属性设置为跨域请求的 URL 地址,
    同时URL中添加一个参数,参数名为 callback,参数值为刚才创建的回调函数的名称。
3.  服务端收到请求后,将数据包装在回调函数的参数中,并将其作为普通的JavaScript 代码返回给客户端。
4.  客户端收到返回的 JavaScript 代码后,会自动执行该代码,从而触发回调函数的执行,
    客户端就可以在回调函数中获取到服务端返回的数据了。

注意:因为script只支持发送GET请求,所以使用JSONP方法也只能使用GET,而且存在一定的风险,因为跨域的JavaScript代码会直接被执行(可能存在恶意代码)

2.CORS(Cross-Origin Resource Sharing),它允许服务器在 HTTP 头中加入一个 Access-Control-Allow-Origin 的字段,指定允许的请求来源,从而让浏览器允许跨域请求。简单来说就是让服务器告诉浏览器:“我允许你这个网页访问我的资源”,从而让跨域请求变得可行。

3.代理,代理方式的基本思路是在服务器端设置一个代理,通过代理将客户端请求转发到目标服务器,从而实现跨域请求。需要注意的是,代理方式可能会对服务器造成一定的压力,另外,代理方式也有一定的局限性,例如无法访问客户端的 Cookie 信息等。

4.H5新增的API:window.postMessage(),使用该方法需要确认浏览器是否支持,并需要对消息来源进行验证,以防止恶意攻击。另外,由于这种通信方式是异步的,因此需要在接收端的代码中添加对消息的处理逻辑。

image.png

HTTP缓存机制(304过程)

如果所有的客户端都直接对服务器发起请求,必然会造成服务器同时处理太多请求,压力过大,于是设计出了缓存,这使得网页打开速度更快,减轻服务器的压力。

此时出现了一个问题,缓存无法及时拿到服务器更新的资源,于是诞生了 Expires,它的值就是一个过期时间,当客户端浏览器拿到这个值以后就知道缓存有没有过期。

请求流程变为:
    浏览器向服务器发出请求 --》 
    服务器再返回资源的时候在响应头里面增加 `Expires`的字段,值为过期时间 --》 
    在过期时间之前,就只需要跟缓存打交道即可

此时又出现了一个问题, Expires返回的是服务器的时间,与客户端时间不一致,出现缓存不准确的问题,于是出现了Cache-Control,它是在http1.1引入的,作用和 Expires类似,但是它的值是过期时长,比如max-age=3600,数字代表秒。相比过期时间,过期时长准确得多。

请求流程变为:
    浏览器向服务器发出请求 --》 
    服务器再返回资源的时候在响应头里面增加 `Cache-Control`的字段,值为过期时长 --》 
    不过期的时候,就只需要跟缓存打交道即可

此时又出现了一个问题,大批量到达过期时间的客户端可能会集中向浏览器发出请求,于是把缓存分为强缓存协商缓存

强缓存指的是在缓存没有过期的时候,浏览器可以直接决定使用缓存。

协商缓存顾名思义,有一个协商的过程,当缓存过期后,浏览器会咨询服务器,是否可以继续使用缓存,根据服务器的返回结果来判断。这个实现过程,需要Last-Modified

请求流程变为:
    浏览器向服务器发出请求 --》 
    服务器再返回资源的时候在响应头里面增加 `Last-Modified`的字段,值为服务器资源最后修改时间 --》 
    浏览器以后每次请求的时候,都带上上一次返回的最后修改时间,服务器拿到这个值,与自己最后修改时间进行对比:

        如果比对结果是没有变化,则会告诉客户端可以使用缓存,返回304状态;
        如果是有资源更新,就给浏览器正常返回资源以及200状态

此时又出现了一个问题,当资源在比较短的时间内(比如1秒内)发生改动, Last-Modified无法感知,会认为没有变化。然后就引入了ETag

 请求流程变为:
    浏览器向服务器发出请求 --》 
    服务器根据文件内容生成唯一标识,并通过`ETag`字段值传送给客户端--》 
    浏览器以后每次请求的时候,都带上`If-None-Match`这个字段,值就是`ETag`,服务器拿到这个值,与自己当前的`ETag`进行对比:
        
        如果比对结果是没有变化,则会告诉客户端可以使用缓存,返回304状态;
        如果是有资源更新,就给浏览器返回新的资源

DNS域名解析

电脑不可以理解网址,所以需要把网址转换为IP地址。一个网址对应一个IP地址,就好像一个人对应一个身份证号码一样,这个转换的过程叫做DNS域名解析。

解析分为两个阶段:本地解析互联网域名服务器解析,如果本地解析完成就返回IP地址,不进行下一步。

本地解析流程:

f94e2694161c3f08e4a6a96fa319cca.jpg

如果本地解析无法找到,则会进入互联网域名服务器解析:

cd2629e518bc1563509a55a464a1520.jpg

重绘与回流

输入URL到呈现页面过程

1.输入URL地址 --> 2.判断缓存情况(见上)--> 3.进行DNS域名解析:浏览器向DNS服务器发起请求,解析该URL中的域名对应的IP地址。DNS服务器是基于UDP的,因此会用到UDP协议 --> 4.TCP三次握手建立连接 --> 5.客户端发送HTTP请求,如果是HTTPS还涉及到加密解密的流程 --> 6.服务器处理请求,并返回HTTP资源 --> 7.TCP四次挥手断开连接 --> 8.浏览器渲染页面(涉及到重绘与回流) --> 9.JS引擎执行过程(同步异步【微任务与宏任务】)

XSS攻击与CSRF攻击

XSS(Cross Site Script 跨站脚本)侧重于注入恶意js代码并执行,一般通过url参数注入或者是输入框注入,分为DOM型攻击、反射型攻击、存储型攻击。 DOM型攻击:恶意代码仅仅只在客户端运行 反射型攻击:浏览器提交恶意代码给服务端,服务端又把恶意代码传回给客户端 存储型攻击:浏览器提交恶意代码给服务端,服务端会把恶意代码存储到数据库,每当有其他用户访问都会,恶意代码都会被扩散

解决方法:根据原理就是需要对客户端和服务器对输入和输出进行严格的把控:比如要对输入的格式进行校验,过滤掉

CSRF(Cross Site Request Forgery 跨站请求伪造)不注入恶意代码,而是在客户端不知情的情况下,伪造成客户端的身份做坏事,