Javascript函数式编程之偏函数

一、前言

在上一篇文章中我简单地提及了函数式编程中的纯函数,那么在这篇文章中就来说说偏函数,如果小伙伴们还不知道什么是纯函数或者感兴趣(有时间)的话,可以点击下方的链接~
Javascript函数式编程之纯函数

二、什么是偏函数?

  • 我个人的理解

所谓偏函数,就是固定一个函数的一个或者多个参数,返回一个新的函数,这个函数用于接受剩余的参数。听起来可能有点迷糊,没事,咱们慢慢来~
首先,我们来看一个简单的例子,下面只是一个普普通通的函数,

function add(a,b){
    return a + b;
}
console.log(add(1,2));//结果3
console.log(add(1,3));//结果4
console.log(add(1,4));//结果5
console.log(add(1,5));//结果6
console.log(add(1,6));//结果7
console.log(add(1,7));//结果8

不知道大家有没有发现,往add()传入的第一个参数全都是相同的,也就是1,对于这样相同的参数,我们已经重复输入了6次。参数少的情况还好办,那参数多的时候就非常不方便了,请往下看:

function add(a,b,c,d,e){
    return a + b + c + d + e;
}
console.log(add(1,2,3,4,5));
console.log(add(1,2,3,1,2));
console.log(add(1,2,3,3,5));
console.log(add(1,2,3,2,11));
console.log(add(1,2,3,3,8));
console.log(add(1,2,3,7,5));

那么有没有什么办法可以让我们对于相同的参数,只输入一次(也就是把他们固定住),对于其他的参数在调用的时候输入就行了呢?答案是肯定的(不然接下来我还怎么扯淡~),它就是本文的主角–偏函数!

  • 揭开偏函数的神秘面纱
    就像上面我所说的一样,偏函数是固定一个函数的一个或多个参数,然后返回一个新函数,所以我们可以定义一个函数,把它命名为partial,这个函数就相当于一个工厂,需要接受一个入参函数,这个工厂用来生产偏函数,按照这个思路,可以写出大概的构架如下:
//入参函数
function add(a,b){
    return a + b;
}
//生产偏函数的工厂,接受一个入参函数,返回一个新的函数,用于接受剩余的参数
function partial(fn,a){
    return function(b){
        return fn(a,b);
    }
}

既然生产偏函数的工厂返回了一个新的函数,所以就用一个变量去接受这个函数,然后在调用该函数的时候再把剩下的参数传入即可。具体代码如下:

//入参函数
function add(a,b){
    return a + b;
}
//生产偏函数的工厂
function partial(fn,a){
    return function(b){
        return fn(a,b);
    }
}
var parAdd = partial(add,1);//变量parAdd接受返回的新函数
console.log(parAdd(2));//在调用的时候传入剩余的参数
console.log(parAdd(3));//在调用的时候传入剩余的参数
console.log(parAdd(4));//在调用的时候传入剩余的参数
console.log(parAdd(5));//在调用的时候传入剩余的参数

固定多个参数的情况:

function add(a,b,c,d,e){
    return a + b + c + d + e;
}
function partial(fn,a,b,c){
    return function(d,e){
        return fn(a,b,c,d,e);
    }
}
var parAdd = partial(add,1,2,3);
console.log(parAdd(2,1));
console.log(parAdd(3,7));
console.log(parAdd(4,8));
  • 偏函数的原理

从上面的演示中我们可以看出,偏函数应用了闭包的原理。

三、偏函数的简单应用

  • Function.prototype.bind()

这是MDN对于bind()的描述:bind() 函数会创建一个新函数(称为绑定函数),新函数与被调函数(绑定函数的目标函数)具有相同的函数体(在 ECMAScript 5 规范中内置的call属性)。当新函数被调用时 this 值绑定到 bind() 的第一个参数,该参数不能被重写。绑定函数被调用时,bind() 也接受预设的参数提供给原函数。一个绑定函数也能使用new操作符创建对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。
不知道大家有木有发现在上面的描述中,出现了几个很重要的表述,创建一个新函数具有相同的函数体调用时的参数被提供给模拟函数,哈哈,这不正和我刚刚说的生产偏函数工厂相似吗。所以对于上面的应用,我们还可以这样改写:

function add(a,b){
    return a + b;
}
var obj = {};
obj.parAdd = add.bind(obj,1);
console.log(obj.parAdd(2));//结果3

嘿嘿,是不是很神奇,小伙伴们也可以自己去尝试哦~

四、结语

好了,以上就是今天偏函数的全部内容了,有什么遗漏和错误的地方希望大家多多指正,感谢阅读!

没有更多推荐了,返回首页