1.什么是纯函数 ?
含义:相同的输入,总是会得到相同的输出,并且在执行过程中没有任何副作用。
2.怎么理解相同的输入总是会的到相同的输出?
例子1 :slice和splice的比较
const arr = [1, 2, 3, 4, 5]
arr.slice(0, 3) //[1, 2, 3]
arr.slice(0, 3) //[1, 2, 3]
arr.splice(0, 3) //[1, 2, 3]
arr.splice(0, 3) //[4,5]
- 上面例子中slice每次传入的参数相同返回值也相同,因此是纯函数。slice返回截取后的数组,不会改变原数组
- 而splice每次传入的参数相同但是返回值不同,因此不是纯函数。splice返回截取后的数组,会改变原数组,因此每次的返回结果都会变化
例子2
// 纯的
function sum(a, b) {
return a + b;
}
const res1 = sum(1, 2); //3
const res2 = sum(1, 2); //3
// 不纯的,修改了自己的入参? fix可以像我下面这样理解么,传入了同一个account(同一个引用地址,内容不同),但是返回值不一样
function withdraw(account, amount) {
account.total -= amount;
return account;
}
const account = {
total: 100
}
const res1 = withdraw(account, 10) //{total:90}
account.total = 20
const res2 = withdraw(account, 10) //{total:10}
再来看一个例子吧
// 不纯的 checkAge 的结果将取决于 minimum 这个可变变量的值。换句话说,它取决于系统状态(system state)
var minimum = 18;
var checkAge = function(age) {
return age >= minimum;
};
var isGrown = checkAge(18) //true
var minimum = 20
var isGrown = checkAge(18) //false
// 纯的
// 第一种方式在函数内部定义minimum变量,不受外部环境影响
var checkAge = function(age) {
var minimum = 18;
return age >= minimum;
};
var isGrown = checkAge(18) //true
var isGrown = checkAge(18) //true
// 第二种方式 使minimum成为一个不可变(immutable)对象
var immutableState = Object.freeze({
minimum: 18
});
var checkAge = function(age) {
return age >= immutableState.minimum;
};
var isGrown = checkAge(18) //true
immutableState.minimum = 20
console.log('immutableState', immutableState)
var isGrown = checkAge(18) //true
3 什么是副作用?
-
“作用”我们可以理解为一切除计算结果之外发生的事情。“作用”本身并没什么坏处,“副作用”的关键部分在于“副”。就像一潭死水中的“水”本身并不是幼虫的培养器,“死”才是生成虫群的原因。同理,副作用中的“副”是滋生 bug 的温床。
-
副作用是在计算结果的过程中,系统状态的一种变化,或者与外部世界进行的可观察的交互。fix 怎么理解?
-
概括来讲,只要是跟函数外部环境发生的交互就都是副作用
-
副作用可能包含,但不限于:
更改文件系统 往数据库插入记录 发送一个 http 请求 可变数据 打印/log 获取用户输入 DOM 查询 访问系统状态
4 纯函数的好处?
- 更容易进行测试,结果只依赖输入,测试时可以确保输出稳定
- 更容易维护和重构,我们可以写出质量更高的代码
- 更容易调用,我们不用担心函数会有什么副作用
- 结果可以缓存,因为相同的输入总是会得到相同的输出
// 简单实现缓存的一个函数 fix怎么理解
var memoize = function(f) {
var cache = {};
return function() {
var arg_str = JSON.stringify(arguments);
cache[arg_str] = cache[arg_str] || f.apply(f, arguments);
return cache[arg_str];
};
};
var squareNumber = memoize(function(x) {
return x * x;
});
squareNumber(4); //16
squareNumber(4); // 从缓存中读取输入值为 4 的结果
squareNumber(5); //25
squareNumber(5); // 从缓存中读取输入值为 5 的结果
5纯函数应用的经典案例有哪些?