函数柯里化

208 阅读2分钟

把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术

为什么要柯里化

  1. 不方便传入参数 如,promise,回调

    // promise的then要执行a方法,但是a方法必传b参数
    function a(b) {
      
    }
    Promise.resolve().then(a.bind(this, 123))
    // Promise.resolve().then(a(b)),需要给then一个函数。若调用a方法,给then的就不是一个函数了
    

    bind方法执行结果返回的是一个未执行的方法,执行时可以继续传入参数,是一个非常典型的柯里化函数,可提高参数的复用

  2. 写了一个方法,但这个方法很多时候调用起来参数是固定的

    function inputTest(reg, value) {
      
    }
    // 有10个表单要验证是否纯数字,那就要调用10次,并且第一个参数是固定的,这个时候就可以用到柯里化
    // 像这样调用就要调10次
    inputTest(/^[0-9]*$/, 123);
    // 柯里化
    const numberTest = inputTest.bind(this, /^[0-9]*$/);
    numberTest(123);
    

如何实现柯里化

柯里化函数会接收到固定参数,然后在柯里化函数里面,返回一个新的函数,接受剩余参数

// 想把a函数的第一个参数固定下来,先写一个柯里化的函数
function a(num1, num2) {
  
}
// 将固定参数传过来
function aCurry(num1) {
	return function(num2) {
    console.log(num1, num2);
  }
}
aCurry(1)(2);

手写实现bind函数

// bind函数除了第一个参数是固定的,接收到的一定是this的指向,其余都不是固定的,所以要控制下this的指向
Function.prototype.mybind = function(thisArg) {
  // thisArg是要bind的this;此this是bind函数本身指向的this,也即调用bind函数那个方法,也即传入的this
  // 健壮性考虑
  if(typeof this !== 'function') {
    return;
  }
  let _self = this;
  // 不需要第一个参数,将第一个参数筛掉
  let args = Array.prototype.clice.call(arguments, 1);
  return function() {
    // 调用原方法本身,且调用新方法时还可能传新参数,要将参数拼齐
    return _self.apply(thisArg, args.concat(Array.prototype.slice.call(arguments)))
  }
}

a.bind(this);