前端面试JavaScript技术

web前端工程师面试题2021(一)

2021-08-26  本文已影响0人  Amanda妍

一、什么是 标签语义化?

答:指的是用富有语义化的标签来创建网页结构,如:header,section,footer,nav从标签名字上可以知道这个标签的作用。
语义化的优点:
1:代码结构清晰,易于阅读,利于开发和维护
2:方便其他设备解析(如屏幕阅读器)根据语义渲染网页。
3:有利于搜索引擎优化(SEO),搜索引擎爬虫会根据不同的标签来赋予不同的权重

二、浏览器渲染机制、重绘、重排

网页的生成过程:
1、html被html解析器解析成DOM树
2、css被css解析器解析成CSS规则树
3、将HTML和CSS合成render树
4、生成布局(flow),即将所有渲染树的所有节点进行平面合成
5、将布局绘制(repaint)到屏幕上
重排(也称回流): 当DOM的变化影响了元素的几何信息(DOM对象的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。 触发:
添加或者删除可见的DOM元素
元素尺寸改变——边距、填充、边框、宽度和高度
重绘:
当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。
触发:
改变元素的color、background、box-shadow等属性

重排优化建议:
分离读写操作
样式集中修改
缓存需要修改的DOM元素
尽量只修改position:absolute或fixed元素,对其他元素影响不大
动画开始GPU加速,translate使用3D变化

三、闭包是指有权访问另一个函数作用域中的变量的函数 ——《JavaScript高级程序设计》

当函数可以记住并访问所在的词法作用域时,就产生了闭包,
即使函数是在当前词法作用域之外执行 ——《你不知道的JavaScript》

闭包用途:
1:能够访问函数定义时所在的词法作用域(阻止其被回收)
2:私有化变量
3:模拟块级作用域
4:创建模块
闭包缺点:会导致函数的变量一直保存在内存中,过多的闭包可能会导致内存泄漏

四、原型和原型链

原型:对象的实例的proto属性指向对象的prototype属性
原型链: 当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是Object.prototype所以这就是我们新建的对象为什么能够使用toString()等方法的原因。
特点: JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。

五、this指向、new关键字

this对象是是执行上下文中的一个属性,它指向最后一次调用这个方法的对象,在全局函数中,this等于window,而当函数被作为某个对象调用时,this等于那个对象。

在实际开发中,this 的指向可以通过四种调用模式来判断。
1、函数调用,当一个函数不是一个对象的属性时,直接作为函数来调用时,this指向全局对象。
2、方法调用,如果一个函数作为一个对象的方法来调用时,this指向这个对象。
3、构造函数调用,this指向这个用new新创建的对象。
4、第四种是 apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。apply接收参数的是数组,call接受参数列表,`` bind方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this指向除了使用new `时会被改变,其他情况下都不会改变。

new关键字的时候发生了什么?

1、首先创建了一个新的空对象
2、设置原型,将对象的原型设置为函数的prototype对象。
3、让函数的this指向这个对象,执行构造函数的代码(为这个新对象添加属性)
4、判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。

六、作用域、作用域链、变量提升

作用域负责收集和维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。(全局作用域、函数作用域、块级作用域)。
作用域链就是从当前作用域开始一层一层向上寻找某个变量,直到找到全局作用域还是没找到,就宣布放弃。这种一层一层的关系,就是作用域链。

七、EventLoop

JS是单线程的,为了防止一个函数执行时间过长阻塞后面的代码,所以会先将同步代码压入执行栈中,依次执行,将异步代码推入异步队列,异步队列又分为宏任务队列和微任务队列,因为宏任务队列的执行时间较长,所以微任务队列要优先于宏任务队列。微任务队列的代表就是,Promise.then,MutationObserver,宏任务的话就是setImmediate setTimeout setInterval

八、原生ajax https://blog.csdn.net/rujin_shi/article/details/83513239

ajax是一种异步通信的方法,从服务端获取数据,达到局部刷新页面的效果。
过程:

创建XMLHttpRequest对象;var xhr = new XMLHttpRequest();
调用open方法传入三个参数 请求方式(GET/POST)、url、同步异步(true/false);
调用send方法传递参数。
监听onreadystatechange事件,当readystate等于4时返回responseText;

九、事件冒泡、捕获(委托)

事件冒泡指在在一个对象上触发某类事件,如果此对象绑定了事件,就会触发事件,如果没有,就会向这个对象的父级对象传播,最终父级对象触发了事件。
事件委托本质上是利用了浏览器事件冒泡的机制。因为事件在冒泡过程中会上传到父节点,并且父节点可以通过事件对象获取到目标节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件,这种方式称为事件代理。

event.stopPropagation() 或者 ie下的方法 event.cancelBubble = true; //阻止事件冒泡

十、浏览器从输入url到渲染页面,发生了什么?

三个方面:
网络篇:
构建请求
查找强缓存
DNS解析
建立TCP连接(三次握手)
发送HTTP请求(网络请求后网络响应)
浏览器解析篇:
解析html构建DOM树
解析css构建CSS树、样式计算
生成布局树(Layout Tree)
浏览器渲染篇:
建立图层树(Layer Tree)
生成绘制列表
生成图块并栅格化
显示器显示内容
最后断开连接:TCP 四次挥手
(浏览器会将各层的信息发送给GPU,GPU会将各层合成,显示在屏幕上)

十一、GET和POST区别(高频)

1.GET在浏览器回退不会再次请求,POST会再次提交请求
2.GET请求会被浏览器主动缓存,POST不会,要手动设置
3.GET请求参数会被完整保留在浏览器历史记录里,POST中的参数不会
4.GET请求在URL中传送的参数是有长度限制的,而POST没有限制
5.GET参数通过URL传递,POST放在Request body中
6.GET参数暴露在地址栏不安全,POST放在报文内部更安全
7.GET一般用于查询信息,POST一般用于提交某种信息进行某些修改操作
8.GET产生一个TCP数据包;POST产生两个TCP数据包

十二、http三次握手

第一步:客户端发送SYN报文到服务端发起握手,发送完之后客户端处于SYN_Send状态
第二步:服务端收到SYN报文之后回复SYN和ACK报文给客户端
第三步:客户端收到SYN和ACK,向服务端发送一个ACK报文,客户端转为established状态,此时服务端收到ACK报文后也处于established状态,此时双方已建立了连接

http四次挥手:

刚开始双方都处于 establised 状态,假如是客户端先发起关闭请求,则:
第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于FIN_WAIT1状态。
第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 + 1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT状态。
第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 + 1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态
服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。

十三、http如何实现缓存

强缓存==>Expires(过期时间)/Cache-Control(no-cache)(优先级高) 协商缓存 ==>Last-Modified/Etag(优先级高)Etag适用于经常改变的小文件 Last-Modefied适用于不怎么经常改变的大文件
强缓存策略和协商缓存策略在缓存命中时都会直接使用本地的缓存副本,区别只在于协商缓存会向服务器发送一次请求。它们缓存不命中时,都会向服务器发送请求来获取资源。在实际的缓存机制中,强缓存策略和协商缓存策略是一起合作使用的。浏览器首先会根据请求的信息判断,强缓存是否命中,如果命中则直接使用资源。如果不命中则根据头信息向服务器发起请求,使用协商缓存,如果协商缓存命中的话,则服务器不返回资源,浏览器直接使用本地资源的副本,如果协商缓存不命中,则浏览器返回最新的资源给浏览器。

十四、输入url后http请求的完整过程

建立TCP连接->发送请求行->发送请求头->(到达服务器)发送状态行->发送响应头->发送响应数据->断TCP连接

十五、跨域通信的几种方式

1、’jsonp(利用script标签没有跨域限制的漏洞实现。缺点:只支持GET请求)
2、CORS(设置Access-Control-Allow-Origin:指定可访问资源的域名)
3、postMessage(message, targetOrigin, [transfer])(HTML5新增API 用于多窗口消息、页面内嵌iframe消息传递),通过onmessage监听 传递过来的数据
4、Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket是高级api,不兼容,但是可以使用socket.io这个库,这个库做了兼容处理

原理:利用webSocket的API,可以直接new一个socket实例,然后通过open方法内send要传输到后台的值,也可以利用message方法接收后台传来的数据。后台是通过new WebSocket.Server({port:3000})实例,利用message接收数据,利用send向客户端发送数据。具体看以下代码:

 <!DOCTYPE html>
 <html>
 <head>
  <title></title>
 </head>
 <body>
  <!-- 
   高级api  不兼容  但是有一个socket.io这个库,是兼容的(一般用这个)

   -->

   <script type="text/javascript">
    let socket = new WebSocket("ws://localhost:3000");//ws协议是webSocket自己创造的
    socket.onopen = function(){
     socket.send("我叫俞华");
    }
    socket.onmessage = function(e){
     console.log(e.data);//你好,我叫俞华!
    }
   </script>
 </body>
 </html>

起一个服务端
一般起的服务是http服务,但是websocket需要起ws服务,ws是webSocket自己定义的。

 /*
  要使用ws协议,那么就要装一个ws的包
 */
 let express = require("express");
 let app = express();
 let WebSocket = require("ws");
 let wss = new WebSocket.Server({port:3000});
 wss.on("connection",function(ws){//先连接
  ws.on("message",function(data){//用message来监听客户端发来的消息
   console.log(data);//俞华
   ws.send("你好,"+data+"!");
  })
 })

如何保证websocket的通信会话是唯一的?
建立WebSocket链接的url上加上时间戳。

5、Node中间件代理cors
6、Nginx反向代理
7、各种嵌套iframe的方式,不常用。
日常工作中用的最对的跨域方案是CORS和Nginx反向代理

十六、能不能说一说浏览器的本地存储?各自优劣如何?

浏览器的本地存储主要分为Cookie、WebStorage和IndexDB, 其中WebStorage又可以分为localStorage和sessionStorage。
共同点: 都是保存在浏览器端、且同源的
不同点:

cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。
存储大小限制也不同,

cookie数据不能超过4K,sessionStorage和localStorage可以达到5M
sessionStorage:仅在当前浏览器窗口关闭之前有效;
localStorage:始终有效,窗口或浏览器关闭也一直保存,本地存储,因此用作持久数据;
cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭

作用域不同

sessionStorage:不在不同的浏览器窗口中共享,即使是同一个页面;
localstorage:在所有同源窗口中都是共享的;也就是说只要浏览器不关闭,数据仍然存在
cookie: 也是在所有同源窗口中都是共享的.也就是说只要浏览器不关闭,数据仍然存在

十七、前端性能优化的几种方式

  1. 浏览器缓存
  2. 防抖、节流
  3. 资源懒加载、预加载
    4.开启Nginx gzip压缩
    三个方面来说明前端性能优化

一: webapck优化与开启gzip压缩
1.babel-loader用 include 或 exclude 来帮我们避免不必要的转译,不转译node_moudules中的js文件
其次在缓存当前转译的js文件,设置loader: 'babel-loader?cacheDirectory=true'
2.文件采用按需加载等等
3.具体的做法非常简单,只需要你在你的 request headers 中加上这么一句:
accept-encoding:gzip
4.图片优化,采用svg图片或者字体图标
5.浏览器缓存机制,它又分为强缓存和协商缓存
二:本地存储——从 Cookie 到 Web Storage、IndexedDB
说明一下SessionStorage和localStorage还有cookie的区别和优缺点
三:代码优化
1.事件代理
2.事件的节流和防抖
3.页面的回流和重绘
4.EventLoop事件循环机制
5.代码优化等等

http1.0、http1.1、http1.x、http2.0的区别

1和1.0相比,1.1可以一次传输多个文件
http1.x解析基于文本,http2.0采用二进制格式,新增特性 多路复用、header压缩、服务端推送(静态html资源)

上一篇下一篇

猜你喜欢

热点阅读