浅聊偏函数

简介: 浅聊偏函数

image.png

什么是偏函数?


首先我们知道,这是一个函数:


function ajax(url, data, callback) {
  // ..
}


这是另外一个函数:


function ajaxTest1(data, callback) {
  ajax('http://www.test.com/test1', data, callback);
}


ajaxTest1 函数相比 ajax 函数,少传了一个参数,它的 url 被固定到了 ajaxTest1 的函数体内;


同理,我们还可以写出 ajaxTest2、ajaxTest3、……、ajaxTestN

如果我们直接写:


function ajaxTest2(data, callback) {
  ajax('http://www.test.com/test2', data, callback);
}
function ajaxTest3(data, callback) {
  ajax('http://www.test.com/test3', data, callback);
}
......
function ajaxTestN(data, callback) {
  ajax('http://www.test.com/testN', data, callback);
}


这样有问题吗?


从“能用就行”的角度看,是可以的;如果是从“设计模式”的角度看,就不太 ok 了!


因为这样写,都没有复用到 ajax 函数呀 😂

基于这种背景,偏函数应用应用而生!


它做了什么?—— 用一个函数封装 ajax 函数,使得封装后的函数 能够先绑定部分参数, 这个封装后的函数就是偏函数;


比方说:

let ajaxTest2 = partial(ajax,'http://www.test.com/test2')


我们用 partial 函数封装了 ajax 函数,然后先绑定了 url 为 'www.test.com/test2' ,封装后的 ajaxTest2 就是偏函数,是函数 ajax 的偏函数;


调用方式不变:


ajaxTest2(data,callback)


这样做的好处就是,我们复用了 ajax,并且封装后的偏函数,需要的传参更少了,这一点十分关键;老观众都知道:在函数式编程中我们提倡:函数的输入和输出,都尽量保持只有 1 个是最佳的。


那么,现在的问题就来了,partial 这个用于封装的函数怎么实现的呢??

和前面提到过的柯里化很像,partial 的目的就是收集参数,然后传给回调函数,它是这样的:


function partial(fn, ...presetArgs) { // presetArgs 是需要先被绑定下来的参数
  return function partiallyApplied(...laterArgs) { //  ...laterArgs 是后续参数
        let allArgs =presetArgs.concat(laterArgs) // 收集到一起
        return fn.apply(this, allArgs) // 传给回调函数 fn
  }
}


这就是基础的偏函数理解。

实际上,针对不同的削减参数的需求,偏函数有不同的写法;但是原理是不变的:

对原始函数二次封装,固定部分参数,返回回调函数,只需要传入更少的参数~~


相关文章
|
1月前
|
安全 程序员 编译器
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
81 11
|
1月前
|
自然语言处理 编译器 Linux
【C++】巧用缺省参数与函数重载:提升编程效率的秘密武器
【C++】巧用缺省参数与函数重载:提升编程效率的秘密武器
|
JavaScript 测试技术 数据库
🎖️typeScrpt中函数重载
在 TypeScript 中,函数重载允许您为同一个函数名称定义多个不同的签名,以处理不同类型的参数或参数数量,从而实现更强的类型推断和函数行为。函数重载能够在运行时根据传递的参数来确定要调用的正确函数签名。
96 0
|
存储 索引 Python
函数之道:探索python函数的奥秘
函数之道:探索python函数的奥秘
|
SQL Java 数据库
Lambda表达式你到哪个境界了?
日常开发中,我们很多时候需要用到Java 8的Lambda表达式,它允许把函数作为一个方法的参数,让我们的代码更优雅、更简洁。所以整理了一波工作中,我常用的,有哪些Lambda表达式。看完一定会有帮助的。
|
JavaScript 前端开发 数据库
✨从纯函数讲起,一窥最深刻的函子 Monad
建议按顺序“食用”。饮水知其源,由 lambda 演算演化而来的闭包思想是 JavaScript 写在基因里的东西,闭包的“孪生子”柯里化,是封装高阶函数的利器。
使用 Lambda 表达式的正确姿势,写得太好了叭
Lambda 表达式非常方便,在项目中一般在 stream 编程中用得比较多。 List<Student> studentList = gen(); Map<String, Student> map = studentList .stream() .collect(Collectors.toMap(Student::getId, a -> a, (a, b) -> a)); 理解一个 Lambda 表达式就三步: 1. 确认 Lambda 表达式的类型 2. 找到要实现的方法 3. 实现这个方法 就这三步,没其他的了。而每一步,都非常非常简单,以至于我分别展开讲一下,你就懂了。
|
XML SQL 开发框架
C#十种语法糖
C#十种语法糖
137 0
C#十种语法糖
|
JavaScript 前端开发
学弟的一张图,让我重学了一遍函数声明和函数表达式!
首先我们要知道,当函数声明与变量命名冲突的时候,要保持着**函数声明优先的原则**