1. 什么是纯函数?
- 概念:不依赖执行上下文,也不影响上下文的变量,输出只由输入决定
// 非纯函数,输入依赖外部变量
let b = 1
function unPure1(a) {
return a + b
}
// 非纯函数,输出改变外部变量
let o = {}
function unPure2(object) {
object.x = 1
return object
}
// 纯函数,输入输出不影响外部变量
function pure(a) {
let b = 1
return a + b
}
2. 纯函数的两个特点
-
相同的输入得到相同的输出
-
没有副作用:不影响外部变量
3. 为什么要用纯函数?
3.1 纯函数的好处
-
可缓存性
-
可移植性/自文档性
-
可测试性
3.1.1 可缓存性
纯函数可以根据输入来做缓存。实现缓存的是一种叫做
memorize
的技术
let squareNum = memorize((x) => { return x * x })
squareNum(4) // 16
squareNum(4) // 从缓存中读取输入值为4的结果 => 16
squareNum(5) // 25
squareNum(5) // 从缓存中读取输入值为5的结果 => 25
vue源码中的一段代码
/**
* 只适用于缓存 接收一个字符串为参数的 fn
*/
export function cached(fn) {
const cache = Object.create(null);
return function cachedFn(str) {
const hit = cache[str];
return hit || (cache[str] = fn(str));
};
}
/**
* Capitalize a string.
*/
export const capitalize = cached((str) => {
return str.charAt(0).toUpperCase() + str.slice(1);
});
capitalize
即为缓存后的函数,如多次调用就会返回缓存后的值,从而节省计算资源,而这一切的前提都建立在 传入cached中的那个函数为纯函数的基础上
3.1.2 可移植性
在任何一个地方都可以随意使用,A项目中使用过的,B项目想要使用直接拿过就可以了
// 不纯的,如果B项目想要用到这个函数,需要将其依赖的其它服务搬过去
const singUp = function(attrs) {
var user = saveUser(attrs)
welcomeUser(user)
}
// 纯的,在B项目使用其功能只需将单个方法搬过去再给其注入需要的参数即可
const singUp = function(db, Email, attrs) {
return function() {
var user = saveUser(db, attrs)
welcomeUser(Email, user)
}
}
3.1.3 可测试性
如果传入相同的参数,它们将始终产生相同的结果。
- 同时纯函数还使得维护和重构代码变得更加容易。正确地使用纯函数可以产生更加高质量的代码。并且也是一种更加干净的编码方式。