函数式编程

函数式编程

纯函数

相同的输入永远会得到相同的输出,而且没有任何可观察的副作用。

slice和splice

1
2
3
4
5
6
7
8
9
let arr = [1, 2, 3, 4, 5]

console.log(arr.slice(0, 3)) // [ 1, 2, 3 ]
console.log(arr.slice(0, 3)) // [ 1, 2, 3 ]
console.log(arr.slice(0, 3)) // [ 1, 2, 3 ]

console.log(arr.splice(0, 3)) // [ 1, 2, 3 ]
console.log(arr.splice(0, 3)) // [ 4, 5 ]
console.log(arr.splice(0, 3)) // []

slice是纯函数,返回数组中指定的部分,不会改变原数组。

splice是不纯的函数,对数组进行操作返回改数组,会改变原数组。

纯函数的好处

因为纯函数对相同的输入始终有相同的结果,所以可以把纯函数的结果缓存起来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 模拟memoize方法的实现
function memoize (f) {
let cache = {}
return function () {
let key = JSON.stringify(argument)
// apply第二个参数可以把argument展开传给f函数
cache[key] = cache[key] || f.apply(this, argument)
return cache[key]
}
}
function getArea (r) {
console.log(r)
return Math.PI * r * 3m i
}
let getAreaWithMemory = memoize(getArea)
console.log(getAreaWithMemory(4))
console.log(getAreaWithMemory(4))
console.log(getAreaWithMemory(4))

柯里化

当一个函数有多个参数的时候先传递一部分参数调用它(这部分参数以后永远不变)。然后返回一个新的函数接收剩余的参数,返回结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function curry (func) {
// ...args接收剩余参数, args获取实际参数
return function curriedFn(...args) {
// 判断实参和形参的个数
if (args.length < func.length) {
// 实参小于形参的个数
return function () {
/**
* 等待剩余的参数,之前的参数加上等待剩余的参数个数
* 第一次调用curry,传递参数,在args缓存下来
* args可以获取调用的参数
* 第二步的参数在return function ()
* 要把args参数和第二次调用参数的值进行合并
*/
return curriedFn(...args.concat(Array.from(arguments)))
}
}
return func(...args)
}
}

const curried = curry(getSum)
console.log(curried(1,2,3))
console.log(curried(1)(2, 3))
  1. 柯里化可以让我们给一个参数传递较少的参数得到一个已经记住了某些固定参数的新函数
  2. 这是一种对函数参数的缓存
  3. 让函数变的更灵活,让函数的粒度更小
  4. 可以把多元函数转换成一元函数,可以组合使用函数产生强大的功能