函数篇
箭头函数
- 没有自己的 this 值,会捕获上下文中的 this 值,在箭头函数中访问 this,它将引用外层作用域中的 this 值,所以调用 obj.fn1()时,输出结果是 window(或 undefined),使用 new 运算符创建实例会导致 TypeError 错误
普通函数
- this 值在运行时动态绑定,
- 当使用普通函数调用(func()):this 会指向全局对象 window
- 当使用调用方式(obj.func()):this 会指向调用该方法的对象
匿名函数/立即执行函数:
- 在这个函数中定义的变量只能在该函数作用域内有效,改变不了全局变量的值
轮询
指在一定的时间间隔内,定时向服务器发送请求,获取最新数据的过程。通常用于从服务器获取实时更新的数据。
缺点:
- 会产生大量的无效请求,浪费带宽和服务器资源,并且对服务器的压力比较大
- 在短时间内频繁地发送请求可能会被服务器视为恶意攻击,导致 IP 被封禁等问题
如何避免?
- 使用 WebSocket、SSE(Server-Sent Events)等技术来实现实时数据更新
- WebSocket 是一种双向通信协议,能狗实现服务器与客户端之间的实时通信
- SSE 是一种居于 HTTP 的单向通信协议,可以实现服务器向客户端推送实时数据。
前端轮询的实现方式
- 基于定时器的轮询: 使用 setInterval()方法来定时发送请求
- 基于递归的轮询:使用 setTimeout()方法来控制下一次请求的时间
与长轮询的区别
- 轮询是在固定的时间间隔内向服务器发送请求,即使服务器没有数据更新也会继续发送请求
- 长轮询时先发送一个请求,服务器如果没有数据更新,则不会立即返回,而是将请求挂起,知道数据更新时再返回结果
函数式编程
一种“编程范式”,一种写编写程序的方法论
主要的编程范式:命令式编程,声明式编程和函数式编程
相比命令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断推进,追曾推到复杂的运算,而非设计一个复杂的执行过程。
1
2
3
4
5
6
7// 命令式编程
var array = [0, 1, 2, 3]
for (let i = 0; i < array.length; i++) {
array[i] = Math.pow(array[i], 2)
}
// 函数式编程
;[0, 1, 2, 3].map((num) => Math.pow(num, 2))纯函数:无状态 + 数据不可变
特性
- 函数内部传入的指定的值,就会返回确定唯一的值
- 不会造成超出作用域的变化
优势:
- 不会产生副作用,提高函数的复用性
- 可读性更强
- 看组装成复杂任务的可能性。
高阶函数: 就是以函数作为输入或输出的函数
- 存在缓存特性,主要利用闭包作用
柯里化
- 把一个多参数函数转化成一个嵌套的一元函数的过程
组合与管道:
- 把很多小的函数组合起来完成更复杂的逻辑。组合函数的执行顺序是从右到左。而管道函数的执行顺序是从左到右。
优点
- 更好的管理状态
- 更简单的复用:固定输入->固定输出,没有其他外部变量影响,并且无副作用。
- 更优雅的组合
- 减少代码量,提高维护性
缺点
- 性能:函数式编程相对于指令式编程,性能绝对是一个短板,因为它往往会对一个方法进行过度包装,从而产生上下文切换的性能开销
- 资源占用:在 JS 中为了实现对象状态的不可变,往往会创建新的对象,因此,它对垃圾回收所产生的压力远远超过其他编程方式
- 递归陷阱:在函数式编程中,为了实现迭代,通常会采用递归操作