纯函数与柯里化
文章目录
- 纯函数
- 柯里化
-
lodash 中的柯里化函数
- 总结
一、纯函数
1.什么是纯函数
纯函数就是相同的输入永远会得到相同的输出,而且没有任何可观察的副作用;而且纯函数就类似数学中的函数(用来描述输入和输出之间的关系),y = f(x)。
下面演示一下纯函数与不纯函数的编码:
let numbers = [1, 2, 3, 4, 5]
// 纯函数
numbers.slice(0, 3)
// => [1, 2, 3]
numbers.slice(0, 3)
// => [1, 2, 3]
numbers.slice(0, 3)
// => [1, 2, 3]
// 不纯的函数 该方法会改变原始数组。
numbers.splice(0, 3)
// => [1, 2, 3]
numbers.splice(0, 3)
// => [4, 5]
numbers.splice(0, 3)
// => []
2.纯函数有什么好处
- 可缓存 --- 因为纯函数对相同的输入始终有相同的结果,所以可以把纯函数的结果缓存起来
- 可测试 ---纯函数让测试更方便
-
并行处理 --- 在多线程环境下并行操作共享的内存数据很可能会出现意外情况 ;纯函数不需要访问共享的内存数据,所以在并行环境下可以任意运行纯函数 (Web Worker)
二、柯里化
- 当一个函数有多个参数的时候先传递一部分参数调用它(这部分参数以后永远不变)
- 然后返回一个新的函数接收剩余的参数,返回结果
代码示例:
function checkAge (base) {
return function (age) {
return base <= age
}
}
var checked = checkAge(18)
console.log(checked(20))
三、lodash 中的柯里化函数
1.lodash
lodash
是一个纯函数的功能库,提供了对数组、数字、对象、字符串、函数等操作的一些方法 ;
lodash的安装请参考官网:https://www.lodashjs.com/
2、lodash函数使用介绍
其余的方法可以查阅官网进行使用:https://www.lodashjs.com/
//加载lodash
const _ = require('lodash');
let arr = [1, 2, 3, 4, 5]
//获取数组的第一个元素
console.log(_.first(arr));
// => 1
//获取数组的最后一个元素
console.log(_.last(arr));
// => 5
2.lodash的柯里化方法
_.curry(func)
功能:创建一个函数,该函数接收一个或多个
func
的参数,如果
func
所需要的参数都被提
供则执行
func
并返回执行的结果。否则继续返回该函数并等待接收剩余的参数。
参数:需要柯里化的函数
返回值:柯里化后的函数
柯里化可以帮我们把任意多元的函数转换成一元函数
curry基本使用
const _ = require('lodash')
// 要柯里化的函数
function getSum (a, b, c) {
return a + b + c
}
// 柯里化后的函数
let curried = _.curry(getSum)
// 测试
curried(1, 2, 3)
// => 6
curried(1)(2)(3)
// => 6
curried(1, 2)(3)
// => 6
下面我们利用lodash的柯里化函数实现一个查找数组中空白元素的功能:
const _ = require('lodash')
//match方法封装成柯里化函数
const match = _.curry(function (reg, str) {
return str.match(reg)
})
//判断字符串是否含有空格
const haveSpace = match(/\s+/g)
//filter方法封装成柯里化函数
const filter = _.curry(function (func, array) {
return array.filter(func)
})
//定义一个查找空白字符的方法
const findSpace = filter(haveSpace)
console.log(findSpace(['John Connor', 'John_Donne']))
柯里化函数原理实现
function curry (func) {
return function curriedFn(...arg) {
// 判断实参和形参的个数
if (arg.length < func.length) {
return function () {
return curriedFn(...arg.concat(Array.from(arguments)))
}
} else {
// 实参和形参个数相同,调用 func,返回结果
return func(...arg)
}
}
}
总结
- 柯里化可以让我们给一个函数传递较少的参数得到一个已经记住了某些固定参数的新函数
- 这是一种对函数参数的'缓存'
- 让函数变的更灵活,让函数的粒度更小
- 可以把多元函数转换成一元函数,可以组合使用函数产生强大的功能