diff --git a/docs/src/pages/FixedArticle/JavaScript/index.md b/docs/src/pages/FixedArticle/JavaScript/index.md index 55a37ca..b7afa8b 100644 --- a/docs/src/pages/FixedArticle/JavaScript/index.md +++ b/docs/src/pages/FixedArticle/JavaScript/index.md @@ -993,4 +993,96 @@ removed === self; // true - 作为一段不超过4kb的小型文本数据,它是由一个名称(Name)、一个值(Value)和其他几个用于控制`cookie`有效期、安全性、适用范围的可选属性组成 - 但是cookie每次请求时都会被发送,如果不使用https对其进行加密,其保存的信息非常容易被窃取,从而导致安全风险 #### cookie常用的一些属性 -- Expires 用于设置cookie的过期时间 \ No newline at end of file +- Expires 用于设置cookie的过期时间 +# 函数式编程 +## 什么是函数式编程 +- 函数式编程是一种编程范式,一种编写程序的方法论 +- 主要的编程范式有三种:命令式编程,声明式编程,函数式编程 +- 相比命令式编程,函数式编程更加强调程序执行的结果而非过程,倡导利用若干简单的执行单元,让计算结果不断渐进,逐层推导复杂的运算,而非设计一个复杂的实行过程 +## 概念 +### 纯函数 +- 函数式编程旨在尽可能的提高代码的无状态性和不变性,要做到这一点,就要学会使用无副作用的函数,也就是纯函数 +- 纯函数式给定的输入返回相同输出的函数,并且要求你所有的内部数据都是不可变的,纯函数=无状态+内部数据不可变(无副作用) +#### 特性: +- 函数内部传入指定的值,就会返回确定唯一的值 +- 不会造成超出作用域的变化,例如:修改全局变量或引用传递的参数 +#### 优势: +- 使用纯函数,我们可以产生可测试的代码 +- 不依赖外部环境计算,不会产生副作用,提高函数的复用性 +- 可读性更强,函数不管是否是纯函数,都会有一个语义化的名称,更便于阅读 +- 可以组装成复杂任务的可能性。符合模块化概念及单一性原则 +### 高阶函数 +- 在编程中,我们需要处理的其实只有两种:数据与关系,而关系就是函数 +- 高阶函数:就是以函数作为输入或输出的函数被称之为高阶函数 +### 柯里化 +- 柯里化是把一个多参数函数转化为一个嵌套的一元函数的过程 +#### 意义: +- 让纯函数更纯,每次接受一个参数,松散解耦 +- 惰性执行 +### 组合与管道 +- 组合函数,目的是将多个函数组合成一个函数 +- 意义:可以把很多小函数组合起来完成更复杂的逻辑 +## 优缺点 +### 优点: +- 更好的管理状态:因为他的宗旨就是无状态,或者说更少的状态,能最大程度减少这些未知、优化代码、减少出错情况 +- 更简单的复用:固定输入 -> 固定输出,没有其他外部变量影响,并且无副作用。这样代码复用时,完全不需要考虑它的内部实现和外部影响 +- 更优雅的组合:往大的说,网页是由各个组件组成的。往小的说,一个函数也有可能是多个小函数组成的,更强的复用性带来更强大的组合性 +- 隐形好处。减少代码量,提高维护性 +### 缺点: +- 性能:函数式编程相对于指令性编程,性能绝对是一个短板,因为他往往会对一个方法进行过度包装,从而产生上下文切换的性能开销 +- 资源占用:在js中为了实现对象状态的不可变,往往会创建新的对象,因此,它对垃圾回收所产生的压力远远超过其他编程方式 +- 递归陷阱:在函数式编程中,对了实现迭代,通常会采用递归操作。 +# 函数缓存 +## 什么是函数缓存 +- 函数缓存就是将函数运算的结果进行缓存,本质上就是利用空间(缓存存储)换时间(计算过程),常用语缓存数据计算结果和缓存对象。缓存只是一个临时的数据存储,它保存数据,以便将来对该数据的请求能够更快的得到处理 +## 如何实现 +实现数据缓存主要依靠以下方法 +- 闭包 +- 柯里化 +- 高阶函数 +## 应用场景 +- 虽然使用缓存效率非常高,但并不是所有场景都适用,因此一定不要滥用函数缓存 +以下几种情况,适合使用缓存: +- 对于昂贵的函数调用,执行负责计算的函数 +- 对于具有有限且高度重复输入范围的函数 +- 对于具有重复输入值的递归函数 +- 对于纯函数,即每次使用特定输入调用时返回想通输入的函数 + +# js数字精度丢失 +```js +0.1+0.2===0.3//false +``` +## 原因 +0.2和0.1 都会先被转化为二进制,然后进行运算,然后运算结果再被转换为十进制 +- 计算机存储双精度浮点数需要先把十进制数转换为二进制的科学计数法的形式,然后计算机以自己的规则{符号位+(指数位+指数偏移量的二进制)+小数部分}存储二进制的科学计数法 +- 因为存储时有位数限制(64位),并且某些十进制的浮点数在转换为二进制时会出现无限循环,会造成二进制的舍入操作(0舍1入),再转换为十进制时就会产生误差 +## 解决方案 +1. 使用toPrecision 凑整并parseFloat转成数字后再显示 +```js +function strip(num, precision = 12) { + return +parseFloat(num.toPrecision(precision)); +} +``` +2. 对于运算类,入加减乘除这一类,则需要先转换为整数,然后进行运算 +3. 可以使用蒂萨方库,例如 Math.js BigDecimal.js等 +# 防抖和节流 +## 什么是防抖和节流 +- 本质上是优化高频率执行代码的一种手段 +定义: +- 节流:n秒内只运行一次,若n秒内重复触发,只有一次生效 +- 防抖,在n秒后执行该事件,若在n秒内被重复触发,则重新计时 +## 区别 +相同点: +- 都可以通过setTimeout实现 +- 目的都是为了降低会调执行频率,节省计算资源 +不同点: +- 函数防抖,在一段连续操作结束后,处理回调函数,利用clearTimeout和setTimeout实现。函数节流,在一段连续的操作中,每一段时间只执行一次,在频率较高的事件中使用来提高性能 +- 函数防抖关注一段时间连续触发的事件,只在最后一次执行,而函数节流是一段时间内只执行一次 +## 应用场景 +防抖在连续的事件,只需触发一次会调的场景有: +- 搜索框搜索输入。只需用户最后一次输入完,再发送请求 +- 手机号、邮箱验证输入检测 +- 窗口大小,只需要窗口调整完成之后,计算窗口大小,防止重复渲染 +节流在间隔一段时间执行一次会调的场景有: +- 滚动加载:加载更多或滚到底部监听 +- 搜索框,搜索联想功能 \ No newline at end of file