小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
前言
到目前为止,我们已经回顾了函数式编程、闭包、高阶函数等函数相关的概念,接下来我们要给大家介绍纯函数、Loadsh、纯函数的好处以及纯函数的副作用
往期
纯函数
纯函数的概念
相同的输入永远会得到相同的输出,而且没有任何可观察的副作用
常用的纯函数进行解析
我们通过数组的slice和splice来进行解析
- 数组的
slice和splice分别是:纯函数和不纯的函数slice返回数组的指定部分,不会改变数组
三次的输出结果是相同的,我们回忆一下纯函数的概念:相同的输入(参数)永远会得到相同的输出,所以let array = [1, 2, 3, 4, 5, 6, 7, 8] console.log(array.slice(0,3)) // [1, 2, 3] console.log(array.slice(0,3)) // [1, 2, 3] console.log(array.slice(0,3)) // [1, 2, 3]slice是纯函数。splice对数组进行操作返回该数组,会改变原数组
三次输出的结果都是不相同的,所以let array = [1, 2, 3, 4, 5, 6, 7, 8] console.log(array.splice(0,3)) // [1, 2, 3] console.log(array.splice(0,3)) // [4, 5, 6] console.log(array.splice(0,3)) // [7, 8]splice是不纯的函数。
我们自己写一个纯函数
function getSum (n1, n2) {
return n1 + n2
}
console.log( getSum(1,2) ) // 3
console.log( getSum(1,2) ) // 3
console.log( getSum(1,2) ) // 3
- 函数式编程是不会保留中间的结算结果,所以变量是不可变的(无状态的)
- 我们可以把一个函数的执行结果交给另一个函数去做处理
Lodash
Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。
纯函数的好处
-
可缓存
-
因为纯函数对相同的输入始终由相同的结果,所以可以把结果存储起来
示例: 用求圆面积进行案例输出
使用函数库: lodash的memoize
// 记忆函数 const _ = require('lodash') function getArea(r) { console.log(r) return Math.PI * r * r } let area = _.memoize(getArea) console.log(area(4)) console.log(area(4)) console.log(area(4))因为我们的函数比较简单所以这里我们在
getArea中做出输出进行查看4 50.26548245743669 50.26548245743669 50.26548245743669可以很明显看出,我们对圆的半径输出仅仅一次,那我们该怎么实现memoize这个方法呢
-
模拟memoize实现
function memoize(f) { // 我们需要内部定义一个对象,存储起来 let cache = {} // 我们在返回结果的时候,我们需要先进行判断 // cache中是否已经有了该返回的结果了,有的话直接返回,没有的话执行一下方法并存储函数执行结果 return function() { // arguments是伪数组 let key = JSON.stringify(arguments) cache[key] = cache[key] || f.apply(f,arguments) return cache[key] } }ok,到这里我们的memoize已经完毕了,测试一下
let area = memoize(getArea) console.log(area(4)) console.log(area(4)) console.log(area(4))输出结果:
4 50.26548245743669 50.26548245743669 50.26548245743669ok,输出结果是一样的,说明我们的思路没有问题
-
-
可测试
- 纯函数让测试更方便:纯函数始终有输入和输出方便单元测试
-
并行处理
- 在多线程环境下并行操作共享的内存数据很可能会出现意外情况
- 纯函数不需要范围内共享的内存数据,所以在并行环境下可以任意运行纯函数(Web Worker),会有同学说诶js不是单线程嘛???你在逗我,es6之后,嘿嘿了解一下Web Worker,不过大多数情况下还是单线程,稍微了解了解哈!
纯函数的副作用:
// 不纯的
let mini= 18
function checkAe(age) {
return age >= mini
}
// 正经纯函数
function checkAge(age) {
let mini = 18
return age >= mini
}
副作用会让一个函数变得不纯(如上例),纯函数的根据相同的输出,如果函数依赖于外部的状态就无法保证相同的输出,就会带来副作用。
副作用的来源
- 配置文件
- 数据库
- 获取用户的输入 所有的外部交互都有可能带来副作用,副作用也使得方法通用性下降,不适合拓展和可用性;同时副作用会给程序中带来安全隐患给程序带来不确定性,但是副作用是不能完全禁止的,尽可能的控制他们在安全可控的范围。
总结
- 纯函数是相同的输入永远会得到相同的输出,而且没有任何可观察的副作用,而且可以在一定程度提高性能,存储相同的输入的数据,不过我们需要注意副作用带来的一些安全隐患哦!