概念
相同的输入始终能得到相同的输出,而且没有可观察的副作用,纯函数肯定需要传参数。比如操作数组的slice函数,就是纯函数。函数式编程不会保留中间运算的结果,所以变量是不可变的
优势
- 因为纯函数对相同的输入有相同的输出,所以纯函数可以缓存输出结果。lodash中的memoize函数即可以实现缓存的功能。 ```javascript // 记忆函数 const _ = require(‘lodash’)
function getArea (r) { console.log(r) return Math.PI r r }
// let getAreaWithMemory = _.memoize(getArea) // console.log(getAreaWithMemory(4)) // console.log(getAreaWithMemory(4)) // console.log(getAreaWithMemory(4))
// 模拟 memoize 方法的实现
function memoize (f) { let cache = {} return function () { let key = JSON.stringify(arguments) //function的参数要传递给f,arguments是一个伪数组,需要进行转换 cache[key] = cache[key] || f.apply(f, arguments) //如果cache中有cache[key]的缓存直接返回缓存,如果没有则调用f函数。调用时需要传入function的参数,可以通过arguments传递,但arguments是伪数组,传入时需要先展开,所以通过f的apply方法,apply的第一个参数可以改变f的this指向,第二个参数可以展开arguments。 return cache[key] } }
let getAreaWithMemory = memoize(getArea) console.log(getAreaWithMemory(4)) console.log(getAreaWithMemory(4)) console.log(getAreaWithMemory(4)) ```
- 可测试
- 纯函数不需要访问共享的内存数据,所以在并行环境下可以任意运行纯函数
副作用
副作用让一个函数变的不纯(如上例),纯函数的根据相同的输入返回相同的输出,如果函数依赖于外部
的状态就无法保证输出相同,就会带来副作用。
所有的外部交互都有可能带来副作用,副作用也使得方法通用性下降不适合扩展和可重用性,同时副作
用会给程序中带来安全隐患给程序带来不确定性,但是副作用不可能完全禁止,尽可能控制它们在可控
范围内发生。