JS 纯函数探索
程序员文章站
2024-02-08 10:33:58
...
什么是纯函数?
纯函数是指不依赖于,且不改变它作用域之外的变量。纯函数同样的输入,一定会得到同样的输出。
作为纯函数需要遵守的规则
1、不得修改传入引用类型
2、不可以调用 Data.now() 或者 Math.random() 等不纯的方法
3、不能调用系统 I/O 的 API
4、不能依赖外部变量
纯函数的作用
1、利用纯函数可以进行单元测试,因为纯函数不需要考虑上下文,只需要考虑输入输出
2、纯函数可以避免不小心修改全局变量而造成的 Bug
3、改变纯函数的执行次序不会对系统造成影响,纯函数的操作是可以并行执行的,因为在多线程环境下并行操作共享的内存数据很可能会出现意外情况,而纯函数不需要访问共享内存
4、可以将需要多次使用,且执行起来很耗时间的纯函数结果缓存起来。使用时可以从缓存中直接调取结果,提高性能
const _ = require('lodash')
function getArea (r){
console.log(r);
return Math.PI * r * r
}
// 通过Lodash的memoize来查看纯函数的可缓存性
let getAreaWithMemory = _.memoize(getArea)
console.log(getAreaWithMemory(4))
console.log(getAreaWithMemory(4))
console.log(getAreaWithMemory(4))
// 模拟memoize 方法的实现
function memoize (fn) {
// 存储函数的执行结果
let cache = {}
return function () {
// 作为键值对中的键
let key = JSON.stringify(arguments)
/**
* 通过key键来判断cache中是否有缓存的结果,
* 如果没有,执行传递进来的函数,
* 如果有直,接返回
*
* apply可以改变函数内部的this
* 第二个参数可以把一个伪数组或者一个数组展开然后将每一项传递给调用者
* */
cache[key] = cache[key] || fn.apply(fn,arguments)
return cache[key]
}
}
let getAreaWithMemory = memoize(getArea)
console.log(getAreaWithMemory(4))
console.log(getAreaWithMemory(4))
console.log(getAreaWithMemory(4))
Lodash 是一个纯函数的功能库,提供了对数组、数字、对象、字符串、函数等操作的一些方法。
最后举几个例子,可以更好的判断函数是否是纯函数
// 纯函数
function a(x) {
return 10 + x
}
// 非纯函数
var num = 10
function a(x) {
// 因为 num 是全局变量
return num + x
}
// 非纯函数
var values = { a: 1 };
var b = 1;
function impureFunction ( a ) {
a = a * b + 2;
return a;
}
// 这里 c 的值依赖于外部变量 b
var c = impureFunction( values.a );