博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
偏函数
阅读量:7225 次
发布时间:2019-06-29

本文共 2087 字,大约阅读时间需要 6 分钟。

定义

维基百科中对偏函数 (Partial application) 的定义为:

In computer science, partial application (or partial function application) refers to the process of fixing a number of arguments to a function, producing another function of smaller arity.

翻译成中文:

在计算机科学中,局部应用是指固定一个函数的一些参数,然后产生另一个更小元的函数。

什么是元?元是指函数参数的个数,比如一个带有两个参数的函数被称为二元函数。

举个简单的例子:

function add(a, b) {    return a + b; } // 执行 add 函数,一次传入两个参数即可 add(1, 2) // 3 // 假设有一个 partial 函数可以做到局部应用 var addOne = partial(add, 1); addOne(2) // 3

个人觉得翻译成“局部应用”或许更贴切些,以下全部使用“局部应用”。

柯里化与局部应用

如果看过上一篇文章,实际上你会发现这个例子和柯里化太像了,所以两者到底是有什么区别呢?

其实也很明显:

柯里化是将一个多参数函数转换成多个单参数函数,也就是将一个 n 元函数转换成 n 个一元函数。

局部应用则是固定一个函数的一个或者多个参数,也就是将一个 n 元函数转换成一个 n - x 元函数。

如果说两者有什么关系的话,引用  中的描述就是:

Curried functions are automatically partially applied.

partial

我们今天的目的是模仿 underscore 写一个 partial 函数,比起 curry 函数,这个显然简单了很多。

也许你在想我们可以直接使用 bind 呐,举个例子:

function add(a, b) {    return a + b; } var addOne = add.bind(null, 1); addOne(2) // 3

然而使用 bind 我们还是改变了 this 指向,我们要写一个不改变 this 指向的方法。

第一版

根据之前的表述,我们可以尝试着写出第一版:

// 第一版// 似曾相识的代码function partial(fn) { var args = [].slice.call(arguments, 1); return function() { var newArgs = args.concat([].slice.call(arguments)); return fn.apply(this, newArgs); }; };

我们来写个 demo 验证下 this 的指向:

function add(a, b) {    return a + b + this.value; } // var addOne = add.bind(null, 1); var addOne = partial(add, 1); var value = 1; var obj = { value: 2, addOne: addOne } obj.addOne(2); // ??? // 使用 bind 时,结果为 4 // 使用 partial 时,结果为 5

第二版

然而正如 curry 函数可以使用占位符一样,我们希望 partial 函数也可以实现这个功能,我们再来写第二版:

// 第二版var _ = {};function partial(fn) { var args = [].slice.call(arguments, 1); return function() { var position = 0, len = args.length; for(var i = 0; i < len; i++) { args[i] = args[i] === _ ? arguments[position++] : args[i] } while(position < arguments.length) args.push(arguments[position++]); return fn.apply(this, args); }; };

我们验证一下:

var subtract = function(a, b) { return b - a; }; subFrom20 = partial(subtract, _, 20); subFrom20(5);

写在最后

值得注意的是:underscore 和 lodash 都提供了 partial 函数,但只有 lodash 提供了 curry 函数。

转载于:https://www.cnblogs.com/guaidianqiao/p/7771506.html

你可能感兴趣的文章
Go 夜读 - 每周四晚上 Go 源码阅读技术分享
查看>>
tranform知多少
查看>>
Android电量优化
查看>>
[爬虫手记] 我是如何在3分钟内开发完一个爬虫的
查看>>
【译】Css Grid VS Flexbox: 实践比较
查看>>
iOS 开发知识索引
查看>>
Linux iptables命令
查看>>
webpack的使用
查看>>
干货 | 基于Go SDK操作京东云对象存储OSS的入门指南
查看>>
D3.js入门
查看>>
一次和前端的相互甩锅的问题记录
查看>>
纯OC实现iOS DLNA投屏功能了解一下
查看>>
RxJava -- fromArray 和 Just 以及 interval
查看>>
LC #75 JS
查看>>
js正则验证代码库
查看>>
常见面试题—css实现垂直水平居中
查看>>
lc682. Baseball Game
查看>>
重学前端-css选择器
查看>>
iOS开发之扫描二维码
查看>>
Android黑科技: 快速找到view所在的xml文件
查看>>