JavaScript 柯里化函数的实现

1. 柯里化函数的定义

在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

函数柯里化的对偶是Uncurrying,一种使用匿名单参数函数来实现多参数函数的方法。例如:

var  foo  =  function ( a )  { 
  return  function ( b )  { 
    return  a  *  a  +  b  *  b ; 
  } 
}

2. 柯里化函数的应用

从定义上我们就可以看出,柯理化函数实际上是减少了我们重复想某一函数中传递固定参数的这一过程,举一个简单的例子,我们定义这样一个函数:

function add(a, b){
	return a + b;
}

这个函数计算了我们传入参数的 a 与 b 的值相加的结果,但是如果们假设在某一场景下,我们大量计算 100 + b 的结果,那么我们可能需要如此调用:

add(100, 1)
add(100, 2)
add(100, 3)
add(100, 4)
// ... ...

可见,在当前场景中,add() 方法的第一个参数始终为 100

同样的场景还有,如:我们创建了一个方法,方法的第一个参数传入一个正则表达式,第二个参数传入要校验的字符串,那么当我们只用一个正则表达式去验证多个结果的话,那么我们需要重复传入这个正则表达式。

柯里化函数就为我们解决了这一问题,利用柯里化的思想,我们可以将一个函数进行封装,返回一个新的函数,这个新的函数只需要我们传入我们需要变动的参数即可,如上面提到的 a + b 的例子,它的柯里化函数写法如下:

function add(a, b){
	return a + b;
}

function add100(b){
	return add(100, b)
}

add100(20) // 120
add100(30) // 130

3. 柯里化函数的实现

显然如果我们使用上面的函数去实现柯理化显然太 Low,我们可以创建一个生成柯里化函数的函数方法,传入一个函数,让其返回一个柯里化的函数(有点工厂模式的意思),所以我们要走以下三步:

  • 将某一函数柯里化
  • 向柯里化函数内传入“固定的参数”
  • 应用柯里化函数

所以这里直接给出实现柯理化函数的方法,分为以下两种:

使用bind函数

function curry(foo) {
  return function () {
    let _null = Object.create(null)
    arguments = Array.prototype.slice.call(arguments)
    return foo.bind(_null, ...arguments)
  }
}

在这里我们使用了ES6的 bind 函数,他有一下特性:

  • bind 是返回一个函数而不是执行一个函数
  • bind 返回的函数保留传入的参数作为默认参数,当再向返回的bind函数传入参数时,会自动将参数传入到后几位参数中

应用:

var addCurry = curry(add)
var add100 = addCurry(100)
console.log(add100(3))  // 103

// 简化书写
console.log(curry(add)(100)(30)) // 130
console.log(curry(add)(100, 20)())

使用apply函数

Function.prototype.curryThis = function () {
  var f = this
  var args = Array.prototype.slice.call(arguments)
  return function () {
    var a = Array.prototype.slice.call(arguments)
    a = args.concat(a)
    return f.apply(null, a)
  }
}

应用:

console.log( add.curryThis(100)(20) ); // 120

同时,柯里化函数是闭包的重要应用点之一

发布了48 篇原创文章 · 获赞 28 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/u012925833/article/details/100775947