前端面试题—面试题整理(5)

一 面试题汇总(Boss直聘分享-金山云外包)

  1. 防抖和节流
  2. 用递归实现阶乘比如传入5,就返回5*4*3*2*1的结果
  3. 箭头函数和普通函数的区别
  4. https和http的区别
  5. 前端缓存
  6. ES6新增哪些特性
  7. Vuex
  8. 原型和原型链
  9. 异步任务分为哪些
  10. 前端性能优化问题
  11. 垂直居中的方式
  12. 怎么理解回流和重绘
  13. 元素显示和隐藏的方法有哪些
  14. 做的比较好的项目,展开讲讲
  15. 深拷贝和浅拷贝,怎么实现一个深拷贝说思路
  16. 内存泄漏是什么,怎么导致的
  17. promise介绍
  18. vue和react的区别
  19. 数组去重的方法?至少说出2种

二 面试题解答(仅供参考)

2.1 防抖和节流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
防抖(Debouncing)和节流(Throttling)是两种用于控制事件触发频率的前端优化技术,
它们都可以限制事件处理函数的执行次数,提高页面性能和用户体验。

1-防抖(Debouncing):
1.1-防抖的基本思想是在事件触发后等待一段时间,如果在这段时间内没有再次触发事件,则执行事件处理函数;
如果在这段时间内又触发了事件,则重新等待一段时间。
1.2-防抖适用于处理一些频繁触发的事件(如输入框输入事件、窗口大小改变事件等),
可以减少不必要的事件处理次数,提高性能。

2-节流(Throttling):
2.1-节流的基本思想是在一段时间内只能触发一次事件处理函数,
即在事件触发后立即执行事件处理函数,然后在一定时间内禁止再次触发事件处理函数。
2.2-节流适用于处理一些需要控制执行频率的事件(如页面滚动事件、鼠标移动事件等),
可以控制事件处理函数的执行频率,提高性能。

总结:防抖和节流都是用于控制事件触发频率的优化技术,它们可以减少不必要的事件处理次数,
提高页面性能和用户体验。需要根据具体的需求和场景来选择使用防抖还是节流。

2.2 用递归实现阶乘比如传入5,就返回5*4*3*2*1的结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
可以使用递归来实现阶乘计算,具体代码如下所示:

function factorial(n) {
// 基线条件:当 n 等于 0 或 1 时,阶乘结果为 1
if (n === 0 || n === 1) {
return 1;
}
// 递归条件:当 n 大于 1 时,计算 n * (n - 1) 的阶乘
return n * factorial(n - 1);
}

// 示例:计算阶乘 5
const result = factorial(5);
console.log(result); // 输出 120

在上面的代码中,factorial 函数用于计算阶乘,通过递归调用自身来实现。
在递归调用过程中,当传入的参数 n 等于 0 或 1 时,即为基线条件,返回 1;
当 n 大于 1 时,递归调用factorial(n -1)来计算(n-1)的阶乘,然后将结果与 n 相乘得到最终结果。

2.3 箭头函数和普通函数的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
箭头函数(Arrow Functions)和普通函数(Regular Functions)在语法和功能上有一些区别,
主要包括以下几点:

1-语法形式:

箭头函数使用箭头 => 来定义,通常由参数列表、箭头和函数体组成。
普通函数使用关键字 function 来定义,通常由关键字、函数名、参数列表、大括号和函数体组成。

2-this 的指向:

箭头函数的 this 指向的是定义时所在的上下文环境中的 this 值,
而不是调用时的 this 值,即箭头函数没有自己的 this,它继承外部作用域的 this。
普通函数的 this 指向的是调用该函数的对象。

3-arguments 对象:

箭头函数没有自己的 arguments 对象,但可以通过 Rest 参数(...args)来获取所有传入的参数。
普通函数可以使用 arguments 对象来获取所有传入的参数。

4-构造函数:

箭头函数不能用作构造函数,不能使用 new 关键字调用,否则会抛出错误。
普通函数可以用作构造函数,使用 new 关键字调用时会创建一个新的对象,并将 this 指向新对象。

5-绑定:

箭头函数的 this、arguments、super 和 new.target 都不能被重新绑定,
且无法通过 call()、apply()、bind() 方法改变它们的值。
普通函数的 this、arguments、super 和 new.target
可以通过 call()、apply()、bind() 方法重新绑定。

6-返回值:

箭头函数如果只有一条语句且不需要返回值,可以省略花括号 {} 和 return 关键字。
普通函数如果只有一条语句且不需要返回值,也可以省略花括号 {} 和 return 关键字。

总的来说,箭头函数和普通函数有着一些区别,主要体现在语法形式、this 的指向、arguments 对象、
构造函数、绑定和返回值等方面。选择使用哪种函数取决于具体的需求和场景。

2.4 https和http的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
HTTP(HyperText Transfer Protocol)和HTTPS(HyperText Transfer Protocol Secure) 
是用于传输数据的两种协议,它们之间的主要区别在于安全性和数据传输方式:

1-安全性:

HTTP 是一种不安全的协议,传输的数据都是以明文的形式传输,容易被窃听和篡改。
HTTPS 则是在 HTTP 的基础上添加了 SSL/TLS 加密层,所有传输的数据都经过加密处理,
可以防止数据被窃听和篡改,提供了更高的安全性。

2-数据传输方式:

HTTP 使用的是 TCP 协议的默认端口号 80 进行数据传输。
HTTPS 使用的是 TCP 协议的默认端口号 443,并且在 HTTP 的基础上添加了 SSL/TLS 加密层,
使用了公钥加密和私钥解密的方式来确保数据的安全传输。

3-认证方式:

HTTP 不提供身份验证功能,无法验证服务器和客户端的身份。
HTTPS 使用了 SSL/TLS 加密层,可以通过数字证书来验证服务器的身份,并建立安全的通信信道。

4-性能:

由于 HTTPS 需要进行加密和解密操作,会增加一定的计算和传输开销,可能会降低一些性能。
但随着硬件技术的发展,现代服务器和浏览器已经能够有效地处理HTTPS加密和解密操作,
性能差距已经不明显。

综上所述,HTTPS 相对于 HTTP 来说具有更高的安全性,能够保护用户的隐私数据和网站的完整性,
因此在涉及到用户隐私信息的场景下,建议使用 HTTPS 来保障数据的安全传输。

2.5 前端缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
前端缓存指的是浏览器或者客户端保存在本地的数据副本,
这些数据可以是静态资源(如 HTML、CSS、JavaScript 文件)、图片、API 响应等,
目的是为了提高用户的访问速度和减少网络流量。

前端缓存主要包括两种类型:浏览器缓存和客户端缓存。

1-浏览器缓存:
浏览器缓存是指浏览器自身在本地保存的一些资源副本,用于加速网页加载和减少网络请求。
常见的浏览器缓存包括:

1.1-HTTP 缓存:通过设置 HTTP 头部控制缓存策略,包括 Cache-Control、Expires、Last-Modified、ETag 等。
1.2-Service Worker 缓存:使用Service Worker技术缓存资源,可实现更灵活的缓存策略和离线访问功能。
1.3-LocalStorage 和 SessionStorage:
使用 Web Storage API 将数据保存在客户端本地,可以持久化存储一些小型数据。

2-客户端缓存:
客户端缓存是指在客户端存储一些数据副本,不依赖于浏览器,可以在不同的浏览器和设备之间共享。
常见的客户端缓存包括:

2.1-CDN 缓存:利用 CDN(内容分发网络)将静态资源缓存到CDN服务器上,提高资源的访问速度和稳定性。
2.2-LocalStorage 和 SessionStorage:同样可以在客户端存储一些小型数据,
与浏览器缓存不同的是,这些数据可以跨浏览器和设备共享。

在开发过程中,可以通过合理设置 HTTP 头部、利用 Service Worker 技术、
使用 CDN 加速等手段来优化前端缓存,提高网站的性能和用户体验。
但需要注意的是,缓存策略的设置需要根据具体的业务需求和资源特性来进行调整,不同的场景可能需要不同的缓存策略。

2.6 ES6新增哪些特性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
ECMAScript 6(ES6)是 JavaScript 的一次重大更新,引入了许多新的语法特性和功能。
以下是 ES6 中一些主要的新增特性:

1-let 和 const 声明:
let 声明变量,具有块级作用域。
const 声明常量,不可重新赋值。

2-箭头函数:
使用箭头 (=>) 定义函数,简化了函数的定义和语法。

3-模板字符串:
使用反引号 (`) 来创建多行字符串,支持变量插值。

4-解构赋值:
可以从数组或对象中提取值,并赋值给变量。


5-默认参数值:
函数参数可以指定默认值,简化了函数的调用。

6-扩展运算符:
使用 ... 语法将数组或对象展开成多个参数。

7-类和继承:
引入了类的概念,支持面向对象的编程风格。

8-模块化:
引入了模块化的语法,可以方便地导入和导出模块。
9-Promise:
引入了 Promise 对象,用于处理异步操作,简化了异步编程。

10-Generators:
引入了生成器函数,可以通过迭代器控制函数的执行流程。

11-Symbol:
引入了 Symbol 数据类型,用于创建唯一标识符。

12-Map 和 Set 数据结构:
引入了 Map 和 Set 数据结构,提供了更方便的键值对和集合操作。

13-新增的数据类型和方法:
引入了新的数据类型如 ArrayBuffer、TypedArray、Map、Set 等,
以及新的方法如 Object.assign、Array.from 等。

14-Async/Await:

引入了 async 和 await 关键字,用于简化 Promise 的使用和处理异步操作。

这些是 ES6 中一些主要的新增特性,它们使得 JavaScript 语言更加强大、灵活和易用,
为 JavaScript 开发提供了更多的可能性和便利性。

2.7 Vuex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Vuex 是一个专门为 Vue.js 应用程序开发的状态管理模式。
它以集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex 集成了 Vue 的响应式机制,并提供了一些工具帮助开发者更容易地理解、调试应用中的状态变化。

Vuex 主要包含以下几个核心概念:

1-State(状态):即存储在应用中的数据状态,可以通过 this.$store.state 访问。

2-Getters(获取器):类似于计算属性,用于从 state 中派生出一些状态,
可以通过 this.$store.getters 访问。

3-Mutations(突变):用于变更 Vuex 的 store 中的状态,只能通过提交 mutation 来修改状态,
而不是直接修改状态,可以通过 this.$store.commit 提交一个 mutation。

4-Actions(动作):类似于 mutation,但是是用于异步操作的,可以包含任意异步操作,
可以通过 this.$store.dispatch 分发一个 action。

5-Modules(模块):将 store 分割成模块,
每个模块都有自己的 state、getters、mutations、actions。

使用 Vuex 可以更好地管理 Vue 应用的状态,并且使得状态变化更可追踪、更易于调试。
通过集中式的状态管理,可以避免组件之间状态传递的复杂性,提高代码的可维护性和可扩展性。

2.8 原型和原型链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
原型(Prototype)和原型链(Prototype Chain)是 JavaScript 中重要的概念,
它们是实现对象继承和属性查找的基础。下面分别介绍一下这两个概念:

1-原型(Prototype):

1.1-在 JavaScript 中,每个对象都有一个原型对象(prototype),
它是一个指向另一个对象的引用。
1.2-对象可以通过 __proto__ 属性来访问它的原型对象。
1.3-当访问一个对象的属性或方法时,如果对象本身没有该属性或方法,
JavaScript 引擎会沿着原型链向上查找,直到找到对应的属性或方法或者查找到原型链的顶端
(即 Object.prototype),如果还没有找到,则返回 undefined。

2-原型链(Prototype Chain):

2.1-原型链是由一系列对象组成的链式结构,每个对象都有一个指向其原型的引用。
2.2-当访问一个对象的属性或方法时,如果对象本身没有该属性或方法,则会沿着原型链向上查找,
直到找到对应的属性或方法或者查找到原型链的顶端(即 Object.prototype)为止。
2.-原型链的顶端是 Object.prototype,它的原型是 null,表示原型链的终点。

在 JavaScript 中,原型和原型链是实现对象之间继承关系的机制。
通过原型链,可以实现对象的属性和方法的共享和继承,从而避免了代码的冗余和重复。
理解原型和原型链对于理解 JavaScript 中的面向对象编程和继承机制非常重要。

2.9 异步任务分为哪些

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
在 JavaScript 中,异步任务可以分为以下几种类型:

1-回调函数(Callback):
回调函数是最基本的异步编程方式,在任务完成后执行的函数被称为回调函数。

2-Promise:
Promise 是一种表示异步操作的对象,它可以在异步操作完成后的成功或失败时触发相应的处理逻辑。

3-Async/Await:
Async/Await 是 ES8/ES2017 中新增的异步编程方式,
基于 Promise,通过 async 和 await 关键字简化了异步代码的书写和理解。

4-事件监听(Event Listener):
通过事件监听的方式来处理异步任务,当特定的事件发生时触发相应的回调函数。


5-定时器(Timers):
使用 setTimeout、setInterval 等定时器函数来延迟执行代码,实现异步任务的调度和执行。

6-Ajax(XMLHttpRequest):
使用 XMLHttpRequest 对象进行异步数据请求和响应处理。

7-Fetch API:
使用 Fetch API 进行网络请求,它提供了更简洁、灵活的方式来处理异步数据请求。

8-Web Workers:
Web Workers 是在后台执行JavaScript代码的一种机制,可以在单独的线程中执行耗时的任务,不阻塞主线程。

以上是常见的 JavaScript 中的异步任务类型,
它们可以根据具体的需求和场景来选择使用,有助于提高代码的执行效率和用户体验

2.10 前端性能优化问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
前端性能优化是提高网站加载速度、用户体验以及搜索引擎排名的重要手段。
以下是一些常见的前端性能优化策略:

1-减少 HTTP 请求:

合并和压缩 CSS、JavaScript 文件。
将多个小图标合并为一张雪碧图。
使用字体图标替代图片图标。
减少页面中引用的外部资源。

2-优化图片:

使用适当的图片格式(如 JPEG、PNG、SVG、WebP)。
压缩图片大小,减少不必要的图片质量。
使用合适的尺寸,避免加载过大的图片。

3-缓存优化:

使用浏览器缓存和服务端缓存来存储静态资源。
使用 HTTP 缓存控制头(如 Cache-Control、ETag、Expires)来设置缓存策略。


4-延迟加载:

延迟加载非必要资源,如图片、视频、JavaScript 文件等。
使用异步加载或按需加载技术,减少页面首次加载时的资源数量。

5-优化 CSS 和 JavaScript:

将 CSS 样式表放在 <head> 标签中,避免渲染阻塞。
将 JavaScript 放在 <body> 标签底部,减少页面加载时的阻塞。
使用外部文件加载,减少页面大小。

6-代码优化:

减少页面重绘和回流,避免不必要的 DOM 操作。
使用事件委托和事件节流,减少事件绑定的开销。
避免使用过多的全局变量和闭包,优化内存使用。

7-使用 CDN 加速:

使用内容分发网络(CDN)来加速静态资源的加载,提高页面加载速度。

8-移动端优化:

使用响应式设计或者移动端专用的布局,提升移动设备上的用户体验。
使用移动端专用的图片格式(如 WebP)和尺寸,减少页面加载时间。

9-监控和优化工具:

使用性能监控工具(如 Lighthouse、WebPageTest、PageSpeed Insights)来评估页面性能,并进行相应的优化。

综上所述,前端性能优化是一个综合性的工作,需要综合考虑各种因素,
从资源优化、代码优化、网络优化等方面进行综合优化,以提高网站的加载速度和用户体验

2.11 垂直居中的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
在前端开发中,实现垂直居中的方式有多种,以下是几种常见的方式:

1-使用 Flexbox 布局:
使用 Flexbox 布局是一种简单有效的方式来实现垂直居中,可以通过设置容器的 display: flex;
和 align-items: center; 属性来实现垂直居中。示例代码如下:

.container {
display: flex;
align-items: center; /* 垂直居中 */
}

2-使用 Grid 布局:
使用 CSS Grid 布局也可以实现垂直居中,可以通过设置容器的 display: grid;
和 align-items: center; 属性来实现垂直居中。示例代码如下:

.container {
display: grid;
align-items: center; /* 垂直居中 */
}

3-使用绝对定位和 transform 属性:
使用绝对定位和 transform 属性也是一种常见的实现垂直居中的方式。
可以通过设置子元素的 position: absolute; 和 transform: translateY(-50%);
属性来实现垂直居中。示例代码如下:

.container {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%); /* 垂直居中 */
}

4-使用表格布局:
使用表格布局也可以实现垂直居中,可以通过设置容器的 display: table;
和子元素的 display: table-cell; 属性来实现垂直居中。示例代码如下:

.container {
display: table;
}
.child {
display: table-cell;
vertical-align: middle; /* 垂直居中 */
}

5-使用 CSS Grid 和 align-self 属性:
在 CSS Grid 布局中,可以使用 align-self: center; 属性将子元素垂直居中。示例代码如下:

.container {
display: grid;
}
.child {
align-self: center; /* 垂直居中 */
}
这些是常见的实现垂直居中的方式,可以根据具体的需求和场景选择合适的方式来实现。

2.12 怎么理解回流和重绘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
回流(Reflow)和重绘(Repaint)是浏览器渲染页面时的两个重要概念,它们是性能优化的关键。
理解它们有助于优化页面性能。

1-回流(Reflow):

回流是指浏览器为了重新渲染部分或全部页面而计算文档中元素的尺寸、位置和布局的过程。
当页面中的部分或全部元素的布局发生变化时(如添加、删除、修改元素的尺寸、位置、隐藏元素等),
浏览器会触发回流,重新计算元素的布局。
回流可能会导致整个文档的重新布局,是一种开销较大的操作,
特别是在复杂页面或频繁触发回流的情况下会影响页面性能。

2-重绘(Repaint):

重绘是指浏览器为了更新页面中元素的视觉效果而重新绘制元素的过程。
当元素的样式发生变化,但不影响其布局时(如修改元素的颜色、背景、文本样式等),
浏览器会触发重绘,重新绘制元素的样式。
重绘不会影响页面的布局,相比回流开销较小,但仍然会消耗一定的资源。
因此,回流和重绘都是浏览器渲染页面时的重要操作,它们都会消耗一定的资源,影响页面的性能。

2.13 元素显示和隐藏的方法有哪些

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
在前端开发中,实现元素显示和隐藏的方法有多种,常见的包括以下几种:

1-使用 CSS 的 display 属性:

使用 CSS 的 display 属性可以控制元素的显示和隐藏。
通过将 display 设置为 none 可以隐藏元素,将display设置为block、
inline 或其他合适的值可以显示元素。
示例代码:

/* 隐藏元素 */
.hidden-element {
display: none;
}
/* 显示元素 */
.visible-element {
display: block;
}

2-使用 CSS 的 visibility 属性:

使用 CSS 的 visibility 属性也可以控制元素的显示和隐藏。
将 visibility 设置为 hidden 可以隐藏元素,设置为 visible 可以显示元素。
不同于 display: none;,visibility: hidden; 会隐藏元素但仍占据页面布局空间。
示例代码:

/* 隐藏元素 */
.hidden-element {
visibility: hidden;
}
/* 显示元素 */
.visible-element {
visibility: visible;
}

3-使用 JavaScript 操作元素的样式:

使用 JavaScript 可以通过操作元素的样式属性来实现显示和隐藏。
通过设置元素的 style.display 属性为 'none' 可以隐藏元素,
设置为其他值(如 'block'、'inline')可以显示元素。
示例代码:

// 隐藏元素
document.getElementById('elementId').style.display = 'none';
// 显示元素
document.getElementById('elementId').style.display = 'block';

4-使用 jQuery 的 show() 和 hide() 方法:

如果项目中使用了 jQuery,可以使用 jQuery 提供的 show() 和 hide() 方法来显示和隐藏元素。
示例代码:

// 隐藏元素
$('#elementId').hide();
// 显示元素
$('#elementId').show();
这些是常见的实现元素显示和隐藏的方法,根据具体的需求和项目情况选择合适的方式进行操作。

2.14 做的比较好的项目,展开讲讲

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1-电子商务平台:

电子商务平台是一个常见的项目类型,您可能开发了一个完整的在线购物网站,
包括用户注册、商品浏览、购物车、订单管理等功能。
在这样的项目中,您可能使用了前端技术(如 HTML、CSS、JavaScript、Vue.js 或 React)、
后端技术(如 Node.js、Express、Django、Spring Boot)以及数据库技术(如 MySQL、MongoDB)等。

2-社交网络应用:

社交网络应用是另一个常见的项目类型,您可能开发了一个类似于 Facebook、Twitter
或 Instagram 的社交平台,包括用户注册、发布动态、添加好友、私信等功能。
在这样的项目中,您可能使用了前端技术、后端技术以及数据库技术,
还可能涉及到用户认证和授权、实时通信等方面的技术。

3-在线教育平台:

在线教育平台是一个提供在线学习资源的项目,您可能开发了一个类似于 Coursera、Udemy
或 Khan Academy 的平台,包括课程管理、学生注册、在线学习、教师管理等功能。
在这样的项目中,您可能使用了前端技术、后端技术以及数据库技术,还
可能涉及到视频流处理、支付系统集成等方面的技术。

2.15 深拷贝和浅拷贝,怎么实现一个深拷贝说思路

1
2
3
4
5
6
7
8
9
10
11
12
13
深拷贝和浅拷贝是在 JavaScript 中常见的两种复制对象的方式。

1-浅拷贝(Shallow Copy):

浅拷贝是指只复制对象的第一层结构,而不复制对象内部的嵌套对象。
当使用浅拷贝复制一个对象时,如果对象内部包含了其他对象的引用,
复制后的对象仍然会共享这些引用,修改其中一个对象的属性会影响另一个对象。

2-深拷贝(Deep Copy):

深拷贝是指复制对象的所有层级结构,包括对象内部的所有嵌套对象。
当使用深拷贝复制一个对象时,复制后的对象是完全独立的,不会共享任何引用,
修改其中一个对象的属性不会影响另一个对象。

2.16 内存泄漏是什么,怎么导致的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
内存泄漏是指程序中已经不再需要的内存仍然占用着内存空间,无法被垃圾回收机制释放,
从而导致系统内存消耗增加,最终可能导致程序性能下降或崩溃。

内存泄漏可能由以下几种情况导致:

1-未释放不再使用的引用:

当一个对象不再被使用时,如果仍然持有对它的引用,那么它不会被垃圾回收机制回收,导致内存泄漏。
例如,在使用闭包时,如果闭包函数持有对外部作用域的变量引用,并且这些变量不再需要,
但是闭包函数仍然存在,那么外部作用域的变量就不会被释放,引发内存泄漏。

2-循环引用:

当两个或多个对象相互引用,并且没有任何一个对象被外部对象引用时,这些对象就形成了循环引用。
如果存在循环引用,即使这些对象不再被外部引用,它们也无法被垃圾回收机制回收,导致内存泄漏。

3-定时器未清理:

在使用定时器时,如果没有及时清理或取消定时器,那么定时器中的回调函数可能会持有对其他对象的引用,
导致这些对象无法被释放,引发内存泄漏。

4-事件监听器未移除:
在 DOM 操作中,如果添加了事件监听器但未及时移除,那么事件监听器可能会持有对其他对象的引用,
导致这些对象无法被释放,引发内存泄漏。

5-大对象缓存:

在应用程序中缓存了大量的对象,但是很少或从未清理这些缓存,导致内存消耗增加,引发内存泄漏。

要避免内存泄漏,需要及时释放不再使用的对象引用,取消不再需要的定时器和事件监听器,
避免形成循环引用,以及合理管理缓存等。
定期进行代码审查和性能测试也有助于及时发现和解决潜在的内存泄漏问题。

2.17 promise介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Promise 是 JavaScript 中用于处理异步操作的一种机制,它可以更优雅、更清晰地处理异步代码,
避免了传统回调函数中的回调地狱问题。
Promise 有以下几个重要特点:

1-状态(State):

Promise 对象有三种状态:Pending(进行中)、Fulfilled(已成功)和Rejected(已失败)。
初始状态是 Pending,当异步操作完成后,可以变为 Fulfilled 或 Rejected。

2-状态转换:

Promise 对象的状态一旦发生变化,就不会再改变。
即从 Pending 转换为 Fulfilled 或 Rejected 后,就会保持这个状态。

3-then 方法:

Promise 实例具有 then 方法,用于指定异步操作的成功和失败的回调函数。
then方法接收两个参数,第一个参数是异步操作成功时的回调函数,第二个参数是异步操作失败时的回调函数。

4-链式调用:

then 方法返回的是一个新的 Promise 对象,因此可以采用链式调用的方式处理多个异步操作。
如果then方法中的回调函数返回了一个Promise对象,那么后续的then方法会等待该Promise对象的状态改变。

5-错误处理:

可以通过 then 方法的第二个参数或 catch 方法来捕获 Promise 对象中发生的错误。

6-静态方法:
Promise 对象还提供了一些静态方法,如 Promise.resolve()、Promise.reject() 和 Promise.all() 等,用于创建 Promise 实例或处理多个 Promise 对象。

2.18 vue和react的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Vue.js 和 React.js 都是流行的前端 JavaScript 框架,
它们有一些共同之处,但也有一些显著的区别。
以下是它们的主要区别:

1-设计理念:

Vue.js 更加注重简单性和直观性,它的设计目标是使开发更加便捷、灵活,并且容易上手。
React.js 更加注重灵活性和可定制性,它的设计目标是构建高效、灵活的用户界面,
通过组件化的方式来构建复杂的用户界面。

2-模板语法:

Vue.js 使用基于 HTML 的模板语法,模板中可以直接使用 HTML 标签和模板语法来描述视图。
React.js 使用 JSX(JavaScript XML)语法,将 HTML 结构和 JavaScript 代码混合在一起,
通过 JavaScript 来描述 UI 组件。

3-组件化:

Vue.js 和 React.js 都支持组件化开发,将用户界面拆分为多个独立的组件,
每个组件都有自己的状态和行为,可以重用和组合。
Vue.js 的组件化更加简单直观,可以使用单文件组件(.vue 文件)来编写组件,包含模板、脚本和样式。
React.js 的组件化更加灵活,通过 JavaScript 函数来定义组件,
可以更灵活地控制组件的渲染逻辑和生命周期。

4-状态管理:
Vue.js有内置的状态管理工具Vuex,用于管理应用的状态和数据流,提供了统一的数据管理和状态管理机制。
React.js 使用的是单向数据流和状态提升的模式,
可以使用 Context API 或第三方状态管理库(如 Redux)来管理应用的状态和数据流。

5-生态系统:

Vue.js的生态系统相对较小,但是有很多官方维护的插件和工具,如 Vue Router、Vuex、Vue CLI 等。
React.js 的生态系统相对较大,有大量的第三方库和工具,
如 React Router、Redux、Next.js、Create React App 等。

总的来说,Vue.js 更注重简单性和直观性,适合快速开发小型和中型应用;
而 React.js 更注重灵活性和可定制性,适合构建大型和复杂的用户界面。选
择哪个框架取决于项目的需求、团队的技术栈和个人偏好。

2.19 数组去重的方法?至少说出2种

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
数组去重是在处理数组时常见的需求,以下是两种常见的数组去重方法:

1-使用 Set 数据结构:

Set 数据结构是ES6中新增的一种数据结构,它类似于数组,但是成员的值都是唯一的,不会出现重复的值。
可以通过将数组转换为 Set,然后再将 Set 转换为数组的方式实现数组去重。
示例代码:

const array = [1, 2, 2, 3, 3, 4, 5, 5];
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // [1, 2, 3, 4, 5]

2-使用 Array.prototype.filter() 方法:

可以利用数组的 filter 方法来过滤出不重复的元素,返回一个新的数组。
在 filter 方法中,通过 indexOf 或 includes 方法来判断元素是否已经存在于新数组中,
如果不存在则添加到新数组中。
示例代码:

const array = [1, 2, 2, 3, 3, 4, 5, 5];
const uniqueArray = array.filter((item, index) => {
return array.indexOf(item) === index;
});
console.log(uniqueArray); // [1, 2, 3, 4, 5]

这两种方法都可以实现数组去重,可以根据具体情况选择使用哪一种方法。
使用 Set 数据结构的方法更加简洁和高效,而使用 filter 方法的方法更容易理解和掌握。

三 图片

四 参考

  • ChatGPT3.5