前端面试总结2

时间:2024-09-29 16:09:20

1.计算圆的周长

class Shape{
constructor(radius=10){
this.radius=radius;
}
diameter(){
return diameter2*this.radius;
}
perimeter(){
const circumference=2*Math.PI*this.radius;
console.log(this.diameter,circumference);
return circumference;
}

}
const cirle=new shape();
circle.perimeter();

2. Js找出数组中的最大值和最小值

在JavaScript中,找到数组中的最大值和最小值有多种方法。这里提供两种常见的解决方案:
方法一:使用Math.max()和Math.min()函数结合 Array.prototype.reduce()

  function findMinMax(arr) {
    return {
        max: arr.reduce((a, b) => Math.max(a, b)),
        min: arr.reduce((a, b) => Math.min(a, b))
    };
}

let numbers = [5, 10, 1, 25, 3];
const result = findMinMax(numbers);
console.log('最大值:', result.max); // 输出:25
console.log('最小值:', result.min); // 输出:1
                    

  方法二:使用for循环 

function findMinMax(arr) {
    let max = arr[0];
    let min = arr[0];

    for(let i = 1; i < arr.length; i++) {
        if(arr[i] > max) {
            max = arr[i];
        } else if(arr[i] < min) {
            min = arr[i];
        }
    }

    return {max, min};
}

let numbers = [5, 10, 1, 25, 3];
const result = findMinMax(numbers);
console.log('最大值:', result.max); // 输出:25
console.log('最小值:', result.min); // 输出:1

3.求字符串的最长子串(这里假设是最长的不重复字符子串)js或者jQuery

在JavaScript中,你可以使用与上面Python示例类似的逻辑来找到最长的不重复字符子串。这里是一个纯JavaScript的实现,不使用jQuery(因为jQuery主要用于简化DOM操作,而不是处理字符串)

function lengthOfLongestSubstring(s) {  
    let start = 0; // 窗口起始位置  
    let maxLength = 0; // 最长子串长度  
    let charMap = {}; // 用于存储字符及其最后出现位置的映射  
  
    for (let end = 0; end < s.length; end++) {  
        // 如果当前字符已经在窗口中,并且其位置在窗口的起始位置之后  
        if (charMap[s[end]] >= start) {  
            // 更新窗口的起始位置为重复字符的下一个位置  
            start = charMap[s[end]] + 1;  
        }  
        // 更新当前字符的最后出现位置  
        charMap[s[end]] = end;  
        // 更新最长子串的长度  
        maxLength = Math.max(maxLength, end - start + 1);  
    }  
  
    return maxLength;  
}  
  
// 示例  
let s = "abcabcbb";  
console.log(lengthOfLongestSubstring(s)); // 输出: 3,最长的不重复字符子串是 "abc"

4. 网站性能优化的方法

1. 压缩文件

压缩HTML、CSS和JavaScript文件:使用gzip压缩算法或minify工具减少文件大小,从而加快下载速度。

2. 优化图片

压缩图片:使用TinyPNG、Kraken等工具压缩图片,去除无用的元数据,减少图片大小。
选择合适的图片格式:如JPEG、PNG或WebP,根据图片内容和用途选择合适的格式。
使用CSS Sprites:将多个小图片合并为一个大图片,减少HTTP请求。

3. 使用CDN加速

内容分发网络(CDN):将网站的静态资源分发到全球各地的服务器上,用户可以从距离最近的CDN服务器获取资源,加速加载速度。

4. 缓存机制

浏览器缓存和HTTP缓存:通过设置适当的缓存头(如Cache-Control和Expires字段),减少对服务器的请求次数。
数据库缓存:缓存数据库查询结果,减少数据库的负载和响应时间。

5. 延迟加载

延迟加载技术:对于大型图片、视频或JavaScript文件等资源,采用延迟加载技术,仅当用户滚动到可见区域时才加载资源,提高页面响应速度。

6. 减少HTTP请求

合并文件:将多个CSS和JavaScript文件合并为一个文件,减少HTTP请求次数。
使用Base64编码:将小图片或字体文件编码为Base64格式,直接嵌入到CSS或HTML文件中,减少HTTP请求。

7. 数据库优化

合理设计数据库结构:避免冗余和复杂的表结构。
使用索引:对经常查询的字段建立索引,提高查询速度。
优化SQL语句:避免使用SELECT *,减少不必要的表连接和子查询。
8. 前端优化

优化HTML、CSS和JavaScript代码:去除冗余和重复的代码,减少文件大小。
使用异步加载:不阻塞页面的渲染和加载,提高页面响应速度。

9. 服务器优化

高性能服务器:选择高性能的服务器硬件和软件配置。
负载均衡:使用负载均衡技术分散服务器负载,提高系统稳定性和可用性。

10. 定期监测和测试

性能测试:使用Google PageSpeed Insights、Pingdom、GTmetrix等工具进行网站性能测试,发现问题并优化。
监控系统:建立监控系统,实时监测网站的性能指标,如响应时间、页面加载时间、带宽使用情况等。

5. 什么原因造成跨域,如何解决跨域问题

跨域产生的原因

跨域问题主要是因为浏览器的同源策略(Same-Origin Policy, SOP)限制。同源策略是一种安全机制,用于限制一个源(origin)的文档或脚本如何与来自另一个源的资源进行交互。源是由协议、域名和端口三者共同组成,如果这三个中的任意一个不相同,那么资源就被认为是跨域的。当浏览器尝试进行跨域请求时,如果请求的资源没有正确的跨域授权,浏览器就会阻止这次请求,以保护用户的安全和隐私。

解决跨域问题的方法

解决跨域问题有多种方法,以下是一些常见的解决方案:

JSONP(JSON with Padding):

原理:利用<script>标签没有跨域限制的特性,通过<script>标签的src属性发送带有callback参数的GET请求。
缺点:仅支持GET方法,且存在安全风险,可能遭受XSS攻击。

CORS(跨域资源共享):
CORS是一个W3C标准,允许浏览器向跨源服务器发出XMLHttpRequest请求。
需要浏览器和服务器同时支持。服务器通过设置响应头(如Access-Control-Allow-Origin)来授权哪些源可以访问资源。
CORS通信过程对用户是无感知的,浏览器会自动处理跨域请求和响应。
代理服务器:
通过在客户端和服务器之间设置一个代理服务器,客户端的所有请求都先发送给代理服务器,代理服务器再将请求转发给目标服务器。
代理服务器可以修改请求和响应的头部信息,实现跨域请求。
常见的代理服务器有Nginx、Node.js中间件等。
iframe + window.name/location.hash/document.domain:
利用iframe和特定的跨域通信技术(如window.name、location.hash、document.domain)实现跨域通信。
这些方法通常涉及到多个页面或iframe之间的复杂交互,适用于特定场景下的跨域通信。
postMessage:
postMessage是HTML5中引入的一种跨文档通信API,允许来自不同源的页面之间进行安全通信。
通过调用window对象的postMessage方法,可以发送数据到指定窗口(即使它们位于不同的域)。
接收方可以通过监听message事件来接收数据。
WebSocket:
WebSocket是一种在单个TCP连接上进行全双工通讯的协议。
它允许服务器主动向客户端推送数据,客户端和服务器之间可以实时交换数据。
WebSocket协议不受同源策略限制,可以实现跨域通信。
修改浏览器设置(仅限开发或测试环境):
在某些情况下,为了开发或测试的需要,可以临时修改浏览器的设置来绕过跨域限制。
例如,在Chrome浏览器中,可以通过启动参数或修改内部设置来禁用同源策略。但这种方法仅适用于开发或测试环境,不建议在生产环境中使用。

6. css垂直居中的方法

四种方法

7. 结合实际场景移动端适配的有哪些方案

1. 响应式布局(Responsive Design)

核心原理:通过CSS的媒体查询(Media Queries)技术,根据不同的屏幕尺寸和分辨率来应用不同的样式规则,从而实现页面的自适应布局。
实现方式:
使用百分比(%)设置元素的宽度,使元素能够随屏幕宽度的变化而自适应调整大小。
利用@media规则编写针对不同屏幕尺寸的CSS样式,如:@media (max-width: 600px) { /* 针对小屏设备的样式 */ }。
优点:
可以根据不同设备提供最佳的用户体验。
无需为每种设备开发单独的网站版本。
缺点:
编写和维护媒体查询可能比较繁琐,特别是在设备类型繁多的情况下。
对于极端屏幕尺寸或分辨率的设备,可能需要额外的适配工作。
2. 弹性盒子布局(Flexbox)
核心原理:Flexbox是一种CSS布局模式,它提供了一种更有效的方式来对容器中的项目进行布局、对齐和分配空间,即使它们的大小未知或是动态变化的。
实现方式:
将容器的display属性设置为flex或inline-flex,以启用弹性盒子布局。
使用flex-direction、justify-content、align-items等属性来定义项目的排列方式和对齐方式。
优点:
提供了更好的灵活性和控制力,能够轻松实现复杂的布局。
简化了对齐和分布空间的代码。
缺点:
在一些老旧的浏览器中可能不被支持(但现代浏览器已广泛支持)。
3. REM单位 + 动态HTML的font-size

核心原理:REM(Root EM)是一个相对单位,它相对于HTML元素的font-size来计算。通过动态调整HTML元素的font-size,可以间接地调整整个页面中使用REM单位的元素大小,从而实现自适应布局。
实现方式:
使用JavaScript监听屏幕尺寸的变化,并动态计算HTML元素的font-size。
将页面中原本使用px单位的元素转换为REM单位。
优点:
易于实现全局的字体大小和元素尺寸调整。
相对于百分比布局,REM单位在嵌套元素中的表现更为直观和可控。
缺点:
需要编写额外的JavaScript代码来处理尺寸变化。
对于不支持REM单位的浏览器(如IE8及以下版本),可能需要额外的兼容性处理。
4. 视口宽度单位(VW/VH)
核心原理:VW(Viewport Width)和VH(Viewport Height)分别代表视口宽度的1%和视口高度的1%。使用这些单位可以直接根据视口的大小来设置元素的大小。
实现方式:
直接在CSS中使用VW或VH单位来设置元素的宽度、高度等属性。
优点:
简化了布局代码,使元素的大小直接与视口大小相关联。
无需编写额外的JavaScript代码或媒体查询。
缺点:
对于一些复杂的布局需求,可能需要结合其他布局技术使用。
在一些老旧的浏览器中可能不被支持(但现代浏览器已广泛支持)。

5. 利用JavaScript库或框架

核心原理:许多JavaScript库或框架(如Bootstrap、Foundation等)提供了内置的移动端适配方案,可以大大简化开发过程。
实现方式:
引入相应的库或框架文件。
使用库或框架提供的组件和布局选项来构建页面。
优点:
提供了丰富的组件和布局选项。
简化了开发过程,提高了开发效率。
缺点:
需要额外学习库或框架的使用方法。
可能会增加页面的加载时间(取决于库或框架的大小)。

8. HTTPS的工作流程

1. 客户端发起HTTPS请求

客户端(通常是Web浏览器)向服务器发送HTTPS请求。URL以https://开头,并且默认使用443端口进行通信。

2. DNS解析

客户端首先通过DNS(域名系统)解析HTTPS URL中的域名,以获取服务器的IP地址。

3. TCP连接建立

客户端与服务器之间通过TCP(传输控制协议)的三次握手建立连接。

4. TLS/SSL握手

服务器发送证书:服务器将配置好的数字证书发送给客户端。证书中包含公钥、证书颁发机构的信息以及其他相关信息。
客户端验证证书:客户端接收到证书后,会对证书进行验证。验证过程包括检查证书的有效性(如是否过期)、验证证书的签名是否可信,并与本地存储的受信任的根证书颁发机构进行比对。
密钥交换:
如果证书验证通过,客户端会生成一个随机的对称密钥(也称为会话密钥),用于后续的数据加密和解密。
客户端使用服务器证书中的公钥对生成的会话密钥进行加密,并将加密后的会话密钥发送给服务器。
服务器接收到加密的会话密钥后,使用服务器的私钥进行解密,获取会话密钥。

5. 加密通信

客户端和服务器都拥有相同的会话密钥,使用该密钥对数据进行加密和解密。
双方之间的通信在传输过程中都是经过加密的,保证了数据的机密性和完整性。

6. 数据传输

客户端和服务器使用会话密钥进行加密通信,传输HTTP请求和响应。

7. 连接关闭

数据传输完成后,客户端和服务器通过TCP的四次挥手关闭连接。

8. 浏览器发起请求到呈现到整个页面的过程

  1. 解析URL: 用户的操作首先会被浏览器的地址栏或某个元素(如链接)解析成完整的URL,包括协议(http/https)、主机名、路径等。
  2. DNS查询: 浏览器查找URL中的域名对应的IP地址,这是通过DNS(Domain Name System)来完成的。
  3. 建立连接: 找到IP后,浏览器发起TCP连接到服务器的特定端口(通常是80或443)。
  4. 发送请求: 创建HTTP请求头部,包含方法(GET、POST等),以及可能的认证信息、内容类型等,并将请求发送到服务器。
  5. 服务器响应: 服务器接收到请求后处理业务逻辑,生成响应,包括HTTP状态码、响应头部(如Content-Type、Set-Cookie等)和响应体。
  6. 接收响应: 浏览器接收到服务器的HTTP响应,解析响应头部,检查状态码(例如200表示成功,404表示未找到等)。
  7. 数据解码: 根据响应头部的Content-Type,浏览器可能还需要对响应体进行解码,如HTML会被解析成DOM结构,JSON会被解析成JavaScript对象。
  8. 渲染页面: 解析后的数据被浏览器用于构建UI,渲染出页面内容。如果是异步加载的内容,可能会通过JavaScript的DOM操作动态插入到页面上。
  9. CSS样式应用: 如果存在CSS文件,浏览器会根据CSS规则对页面进行样式渲染。
  10. JavaScript执行: 如果响应中有脚本(如JS文件或HTML的<script>标签),浏览器会按顺序执行这些脚本,可能导致页面交互和动态效果的变化。
  11. 事件循环和定时器: JavaScript引擎会持续运行,处理用户交互事件,执行定时器和周期性的任务。
     

9. ES6有哪些新的语法

ES6(ECMAScript 2015)是JavaScript语言的一个重要更新版本,它引入了许多新的语法特性和改进。以下是ES6中一些主要的新语法特性:

1. let和const

  • let:用于声明块级作用域的局部变量,与var不同,let声明的变量不会在声明前被提升(hoisting),且不允许在同一作用域内重复声明。
  • const:用于声明常量,一旦赋值后,其值就不能被重新赋值(对于基本数据类型)。对于引用类型(如对象或数组),const声明的常量不能指向另一个对象,但对象的属性或数组的元素是可以被修改的。

2. 模板字符串

  • 使用反引号(`)包裹的字符串,可以嵌入表达式(使用${}包裹)。模板字符串支持多行字符串和字符串插值。

3. 解构赋值

  • 允许从数组或对象中提取数据,并将其赋值给声明的变量。这包括数组解构和对象解构,使得数据访问和赋值更加直观和方便。

4. 箭头函数

  • 提供了更简洁的函数写法,使用=>符号定义函数。箭头函数不绑定自己的this,arguments,super,或new.target。这些函数表达式更适合用于非方法函数,并且它们不能用作构造函数。

5. 函数参数默认值

  • 允许为函数的参数设置默认值,如果调用函数时未提供该参数,则使用默认值。

6. 展开运算符(Spread Operator)和剩余参数(Rest Parameters)

  • 展开运算符(...):用于在函数调用时展开数组或对象,或在数组字面量中展开数组。
  • 剩余参数(...):用于在函数定义时收集多余的参数到一个数组中。

7. 对象字面量增强

  • 允许在对象字面量中直接写入变量名和函数作为对象的属性和方法,而不需要使用:来分隔键和值。
  • 允许计算属性名,即属性名可以是一个表达式。

8. 新增的数据类型

  • Symbol:一种新的原始数据类型,表示独一无二的值。

9. Map和Set

  • Map:是一种集合,它保存键值对,并且能够记住键的原始插入顺序。
  • Set:是一种集合,它允许你存储任何类型的唯一值,无论是原始值或者是对象引用。

10. Promise

  • 是一种用于异步计算的对象。一个promise代表了一个最终可能完成(或失败)及其结果值的异步操作。

11. Class和继承

  • ES6引入了class关键字,用于定义类。类是基于原型的继承机制的语法糖。
  • 允许使用extends关键字实现类的继承。

12. Modules

  • ES6引入了模块(Module)的概念,用于实现JavaScript的模块化编程。通过importexport语句,可以导入和导出模块中的功能。

13. 其他新特性

  • 二进制和八进制字面量:允许在数字字面量前添加0b0o来表示二进制和八进制数。
  • for...of循环:用于遍历可迭代对象(如数组、Map、Set等)的值。
  • Object.assign():用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
  • Object.keys()Object.values()Object.entries():分别用于获取对象的所有键、所有值、所有键值

10. 弹性盒子模型flex

flex详解

11. 隐藏元素的方法有哪些,有什么区别(重排重绘)

1. 使用display: none;

效果:元素在页面渲染中直接删除,不会占据任何空间,也无法通过CSS选择器选择该元素。
重排重绘:此方法会导致重排,因为元素已经从渲染树中移除,后续的操作不会影响到该元素,也不会触发其他元素的重排或重绘。

2. 使用visibility: hidden;

效果:元素仍然占据空间,但内容不可见。无法通过CSS选择器选择隐藏的元素进行显示,但可以通过其他方式(如JavaScript)来恢复其可见性。
重排重绘:此方法不会导致重排,因为元素的布局位置没有改变,但会导致重绘,因为元素的可见性发生了变化。

3. 使用opacity: 0;

效果:元素仍然占据空间,且其布局位置不变,只是内容的透明度被设置为0,使得元素不可见。
重排重绘:此方法同样不会导致重排,因为元素的布局位置没有改变,但会导致重绘,因为元素的透明度属性发生了变化。

4. 使用position: absolute;配合大偏移量

效果:通过将元素定位到屏幕外的位置(如top: -9999px; left: -9999px;),使其不可见。元素仍然保留在DOM中,并占据原有的布局空间。
重排重绘:此方法可能会导致重排,因为元素的定位属性发生了变化,同时也可能导致重绘,因为元素的位置被移动到了屏幕外。

5. 使用transform: scale(0);

效果:通过缩放元素至0,使其不可见。元素仍然占据空间,但内容被缩小到不可见的程度。
重排重绘:此方法通常不会导致重排,因为元素的布局位置没有改变(尽管其视觉尺寸变为了0),但可能会触发重绘,因为元素的变换属性发生了变化。
6. 使用width: 0; height: 0; overflow: hidden;
效果:将元素的宽度和高度都设置为0,并通过overflow: hidden;防止内容溢出。这种方法通常用于隐藏内部内容,但元素本身仍然占据一个极小的空间。
重排重绘:此方法可能会导致重排,因为元素的尺寸属性发生了变化,但重绘的影响相对较小,因为元素本身已经变得非常小。

总结

不同的隐藏元素方法在重排和重绘方面有不同的影响。display: none;是最彻底的隐藏方式,因为它会从渲染树中移除元素,从而避免重排和重绘。而visibility: hidden;和opacity: 0;则保留了元素在DOM中的位置,但改变了其可见性,可能会导致重绘。position: absolute;配合大偏移量和transform: scale(0);则可能同时影响重排和重绘,具体取决于元素的原始布局和定位情况。width: 0; height: 0; overflow: hidden;则主要用于隐藏内部内容,对重排和重绘的影响相对较小。在选择隐藏元素的方法时,应根据具体需求和性能考虑来做出选择。

12.闭包常见的场景

1. 封装
闭包可以用于创建私有变量和函数,从而实现信息隐藏和封装。这在JavaScript中特别有用,因为JavaScript本身并没有提供类似于Java或C++的私有成员的语法。通过闭包,可以在函数内部定义变量和函数,并通过返回的函数来访问这些私有成员,从而避免外部直接访问和修改。

2. 函数式编程
在函数式编程中,闭包是非常有用的工具。通过使用闭包,可以创建高阶函数(即接受函数作为参数或返回函数的函数)、延迟执行函数、柯里化等功能。这些功能使得函数式编程更加灵活和强大。

3. 定时器和事件处理
在处理定时器和事件时,闭包可以帮助保存局部状态,从而在稍后的时间点执行所需的逻辑。例如,在使用setTimeout或setInterval时,可以通过闭包来传递和保存需要的参数和状态,确保在回调函数执行时能够访问到这些值。

4. 模块模式
闭包可以用于创建模块,将相关的函数和数据封装在一起,提供一种更加模块化的编程方式。这种模块化的方式有助于减少全局变量的污染,提高代码的可维护性和可重用性。

5. 回调函数
在异步编程中,闭包常常与回调函数一起使用。由于异步操作不会立即返回结果,而是需要等待一段时间后才能得到结果,因此可以通过闭包来捕获周围作用域的状态,并在回调被触发时使用这些状态。这样,即使在异步操作完成后,也能访问到操作开始时的状态信息。

6. 循环中的异步操作
在循环中进行异步操作时,使用闭包可以解决由于JavaScript中的变量提升导致的问题。由于JavaScript的变量作用域特性,循环中的异步操作可能会捕获到循环结束时的变量值,而不是循环过程中的某个特定值。通过使用闭包,可以确保在异步操作完成时能够获取到正确的循环变量值。

7. 缓存
利用闭包可以缓存计算结果,避免重复计算,提高程序的性能。例如,可以创建一个闭包来封装一个计算密集型的函数,并在闭包内部维护一个缓存来存储已经计算过的结果。当再次调用该函数时,可以先检查缓存中是否已经存在结果,如果存在则直接返回缓存中的结果,而无需重新计算。

8. 节流和防抖
在事件处理中,节流(throttle)和防抖(debounce)是两种常用的优化技术。节流可以限制函数的执行频率,确保在指定的时间间隔内只执行一次函数;防抖可以确保函数在事件停止触发一定时间后才执行。这两种技术都可以通过闭包来实现,因为它们都需要在函数外部保存一些状态信息(如定时器ID等),并在函数内部根据这些状态信息来决定是否执行目标函数。

9. 柯里化
柯里化是一种将多个参数的函数转换为一系列接受单个参数的函数的过程。通过闭包,可以轻松地实现函数的柯里化。柯里化后的函数可以更加灵活地使用,例如可以部分应用参数、实现参数的复用等。

10. 迭代器和生成器
在JavaScript中,迭代器和生成器是与闭包紧密相关的概念。迭代器用于遍历数据结构(如数组、对象等),而生成器则是一种特殊的函数,可以暂停和恢复执行。通过闭包,可以创建复杂的迭代器或生成器逻辑,并在需要时保存和恢复执行状态。

综上所述,闭包在编程中有着广泛的应用场景,包括封装、函数式编程、定时器和事件处理、模块模式、回调函数、循环中的异步操作、缓存、节流和防抖、柯里化以及迭代器和生成器等。这些应用场景展示了闭包在提高代码模块化、灵活性和性能方面的巨大潜力。

组件通信

项目中是怎么管理分支的临时bug一般怎么做

HTTP的状态码有哪些

HTTP状态码(HTTP Status Code)是当Web服务器响应HTTP(超文本传输协议)请求时,用来表示请求成功或失败的数字代码。这些状态码由三位数字组成,并且被分为五类,以不同的第一位数字表示:

1xx(信息性状态码):表示接收到请求,正在处理。

  • 100 Continue:客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。
  • 101 Switching Protocols:服务器已经理解了客户端的请求,并将通过Upgrade消息头部的字段切换到一个由该请求所指示的不同的协议。

2xx(成功状态码):表示请求已成功被服务器接收、理解、并接受。

  • 200 OK:请求成功。
  • 201 Created:请求已被满足,并且服务器创建了一个新的资源。
  • 202 Accepted:服务器已接受请求,但尚未处理。
  • 203 Non-Authoritative Information:服务器已成功处理了请求,但返回的实体头部元信息不是在原始服务器上有效的确定集合,而是来自本地或者第三方的拷贝。
  • 204 No Content:服务器成功处理了请求,但不需要返回任何实体内容,并且希望返回更新了的元信息。
  • 205 Reset Content:服务器成功处理了请求,且没有返回任何内容。
  • 206 Partial Content:服务器成功处理了部分GET请求。

3xx(重定向状态码):表示需要客户端采取进一步的操作才能完成请求。

  • 300 Multiple Choices:被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。
  • 301 Moved Permanently:请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。
  • 302 Found:请求的资源现在临时从不同的URI响应请求。
  • 303 See Other:对应当前请求的响应可以在另一个URI上被找到,且客户端应当采用GET的方式访问那个资源。
  • 304 Not Modified:如果客户端发送了一个带条件的GET请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。
  • 305 Use Proxy:被请求的资源必须通过指定的代理才能被访问。
  • 307 Temporary Redirect:请求的资源现在临时从不同的URI响应请求。

4xx(客户端错误状态码):表示请求包含错误语法或无法完成请求。

  • 400 Bad Request:由于明显的客户端错误(例如,格式错误的请求语法,太大的无效请求头,或者错误的URI),服务器不能完成对请求的处理。
  • 401 Unauthorized:请求要求身份验证。
  • 403 Forbidden:服务器理解请求客户端的请求,但是拒绝执行此请求。
  • 404 Not Found:服务器无法根据客户端的请求找到资源(网页)。
  • 405 Method Not Allowed:请求行中指定的请求方法不能被用于请求相应的资源。
  • 406 Not Acceptable:根据客户端请求的范围,服务器无法提供响应。
  • 407 Proxy Authentication Required:请求要求代理的身份验证,以授权请求。
  • 408 Request Timeout:请求超时。
  • 409 Conflict:由于和被请求的资源的当前状态相冲突,请求无法完成。
  • 410 Gone:所请求的资源已经不再可用,而且没有任何已知的转发地址。
  • 411 Length Required:服务器拒绝在没有定义Content-Length头的情况下接受请求。
  • 412 Precondition Failed:服务器未满足请求者在请求中设置的其中一个前提条件。
  • 413 Payload Too Large:请求实体过大,服务器无法处理,因此拒绝请求。
  • 414 URI Too Long:请求的URI(通常是网址)过长,服务器无法处理。
  • 415 Unsupported Media Type:请求的格式不受请求页面的支持。
  • 416 Range Not Satisfiable:客户端请求的范围无效。
  • 417 Expectation Failed:服务器无法满足Expect头信息指定的预期要求。

5xx(服务器错误状态码):表示服务器在处理请求的过程中遇到了错误。

  • 500 Internal Server Error:服务器遇到了一个未曾预料到的情况,导致了它无法完成对请求的处理。
  • 501 Not Implemented:服务器不支持当前请求所需要的某个功能。
  • 502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
  • 503 Service Unavailable:由于临时的服务器维护或者过载,服务器当前无法处理请求。
  • 504 Gateway Timeout:作为网关或者代理的服务器没有及时从上游服务器收到请求。
  • 505 HTTP Version Not Supported:服务器不支持请求中所用的HTTP协议版本。

事件循环

事件循环(Event Loop)是JavaScript或Node.js中用于处理异步操作的一种关键机制,它允许JavaScript引擎在单线程环境中高效地执行代码,同时处理各种事件和回调。以下是对事件循环的详细解释:

一、基本概念

单线程:JavaScript是单线程的,这意味着它一次只能执行一个任务。为了处理多任务,JavaScript引入了事件循环机制。
任务队列:任务队列(也称为事件队列)用于存储等待执行的任务。这些任务包括异步操作的回调函数等。
主线程:主线程是执行JavaScript代码的地方,包括同步代码和从任务队列中取出的异步任务。

二、事件循环的工作流程

执行同步代码:当JavaScript代码开始执行时,主线程会按顺序执行同步代码。
处理异步操作:当遇到异步操作时(如setTimeout、Promise、网络请求等),主线程会将该操作交给相应的Web API处理,并继续执行后续代码。
异步操作完成:当异步操作完成后,相应的回调函数会被添加到任务队列中等待执行。
事件循环检查:主线程在执行完当前同步任务后,会进入事件循环检查阶段。在这个阶段,主线程会不断检查任务队列,查看是否有待处理的事件。
执行回调函数:如果任务队列中有待处理的事件,主线程会从队列中取出第一个事件,将其回调函数推入调用栈中执行。这个过程是连续的,直到队列为空。

三、宏任务与微任务

宏任务(MacroTasks):包括整体代码script、setTimeout、setInterval、I/O操作、UI渲染、DOM事件、网络请求等。它们在每个事件循环的迭代中按顺序执行。
微任务(MicroTasks):包括Promise.then、MutationObserver、process.nextTick(Node.js环境)等。微任务的优先级高于宏任务,它们会在当前宏任务完成后立即执行,而不是等待下一个事件循环迭代。

四、执行顺序示例

以下是一个简单的执行顺序示例,用于说明宏任务和微任务的执行顺序:

console.log('Script start');  
setTimeout(function() {  
    console.log('setTimeout');  
}, 0);  
Promise.resolve().then(function() {  
    console.log('promise1');  
});  
console.log('Script end');

执行顺序将会是:

Script start  
Script end  
promise1  
setTimeout

在这个例子中,尽管setTimeout被设置为0毫秒后执行,但由于它是一个宏任务,所以它会在所有同步代码和微任务(promise1)执行完毕后才被执行。

五、总结

事件循环是JavaScript中处理异步操作的核心机制。它允许JavaScript引擎在单线程环境中高效地执行代码,同时处理各种事件和回调。通过宏任务和微任务的区分,JavaScript能够确保异步操作的顺序性和响应性。在实际开发中,理解和利用事件循环机制对于编写高效、可维护的JavaScript代码至关重要