函数式编程中的函数指的就是纯函数,纯函数就是相同的输入始终会用相同的输出,而且没有可观察到的副作用。纯函数就类似数学中的函数(用来描述输入和输出之间的关系)y = f(x)。数组的slice和splice方法分别就是纯函数和不纯的函数:
slice(start, end)返回数组中的指定部分,不会改变原数组splice(start, length)对数组进行操作返回该数组,会改变原数组
函数式编程中不会保留中间结果,所以变量是不可变的(无状态的)。我们可以把一个函数的执行结果传递给另一个函数继续进行处理。
let numbers = [1,2,3,4,5,6,7]
console.log(numbers.slice(0, 3)) // [1,2,3]
console.log(numbers.slice(0, 3)) // [1,2,3]
console.log(numbers.slice(0, 3)) // [1,2,3]
console.log(numbers.splice(0, 3)) // [1,2,3]
console.log(numbers.splice(0, 3)) // [4,5]
console.log(numbers.splice(0, 3)) // []
优势:
一、可缓存:
因为纯函数具有相同的输入始终有相同的输入这个特点,所以可以把纯函数的结果缓存起来。
const _ = require('lodash')
function getArea (r) {
return Math.PI * r * r
}
const getCatchedArea = _.memoize(getArea)
console.log(getCatchedArea(4))
console.log(getCatchedArea(4))
自己模拟一个memoize函数:
function memoize (fn) {
const catch = {}
return function () {
const key = JSON.stringify(arguments)
return catch[key] || fn.apply(fn, arguments)
}
}
二、可测试:
因为纯函数始终有输入和输出,而单元测试其实就是在断言这个函数结果。所以,我们所有的纯函数都是可测试的函数。
三、并行处理:
1、多线程环境下并行操作共享内存,比如全局变量,会发生多个线程同时去修改同一个全局变量。造成内存数据会出现意外的情况;
2、由于纯函数是一个封闭的空间,因为纯函数只依赖于参数。这样纯函数就不需要访问共享的内存数据,所以在并行环境下可以任意运行纯函数。