摘要:在计算机科学中,偏函数是指固定一个函数的一些参数,然后产生另一个更小元的函数。希望阅读本篇文章以后大家有所收获,帮助大家对JavaScript的理解更加深入。
定义
维基百科中对偏函数 (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
个人觉得翻译成“局部应用”或许更贴切些,以下全部使用“局部应用”。
柯里化与局部应用
如果看过上一篇文章《JavaScript基础教程 20分钟掌握函数柯里化 》,实际上你会发现这个例子和柯里化太像了,所以两者到底是有什么区别呢?
其实也很明显:
柯里化是将一个多参数函数转换成多个单参数函数,也就是将一个 n 元函数转换成 n 个一元函数。
局部应用则是固定一个函数的一个或者多个参数,也就是将一个 n 元函数转换成一个 n - x 元函数。
如果说两者有什么关系的话,引用 functional-programming-jargon 中的描述就是:
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);
本文由职坐标整理并发布,了解更多内容,请关注职坐标WEB前端JavaScript频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号