js函数柯里化

维基百科上说道:柯里化,英语:Currying(果然是满满的英译中的既视感),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

// 普通的add函数
function add(x, y) {
   return x + y
}

// Currying后
function curryingAdd(x) {
   return function (y) {
       return x + y
   }
}

add(1, 2)           // 3
curryingAdd(1)(2)   // 3

实际上就是把add函数的x,y两个参数变成了先用一个函数接收x然后返回一个函数去处理y参数。现在思路应该就比较清晰了,就是只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。

1.参数复用

// 正常正则验证字符串 reg.test(txt)

// 函数封装后
function check(reg, txt) {
  return reg.test(txt)
}

check(/\d+/g, 'test')       //false
check(/[a-z]+/g, 'test')    //true

// Currying后
function curryingCheck(reg) {
  return function(txt) {
      return reg.test(txt)
  }
}

var hasNumber = curryingCheck(/\d+/g)
var hasLetter = curryingCheck(/[a-z]+/g)

hasNumber('test1')      // true
hasNumber('testtest')   // false
hasLetter('21212')      // false

上面的示例是一个正则的校验,正常来说直接调用check函数就可以了,但是如果我有很多地方都要校验是否有数字,其实就是需要将第一个参数reg进行复用,这样别的地方就能够直接调用hasNumber,hasLetter等函数,让参数能够复用,调用起来也更方便。

2.提前确认

var on = function(element, event, handler) {
  if (document.addEventListener) {
      if (element && event && handler) {
          element.addEventListener(event, handler, false);
      }
  } else {
      if (element && event && handler) {
          element.attachEvent('on' + event, handler);
      }
  }
}

var on = (function() {
  if (document.addEventListener) {
      return function(element, event, handler) {
          if (element && event && handler) {
              element.addEventListener(event, handler, false);
          }
      };
  } else {
      return function(element, event, handler) {
          if (element && event && handler) {
              element.attachEvent('on' + event, handler);
          }
      };
  }
})();

//换一种写法可能比较好理解一点,上面就是把isSupport这个参数给先确定下来了
var on = function(isSupport, element, event, handler) {
  isSupport = isSupport || document.addEventListener;
  if (isSupport) {
      return element.addEventListener(event, handler, false);
  } else {
      return element.attachEvent('on' + event, handler);
  }
}

我们在做项目的过程中,封装一些dom操作可以说再常见不过,上面第一种写法也是比较常见,但是我们看看第二种写法,它相对一第一种写法就是自执行然后返回一个新的函数,这样其实就是提前确定了会走哪一个方法,避免每次都进行判断。

3.延迟运行

Function.prototype.bind = function (context) {
  var _this = this
  var args = Array.prototype.slice.call(arguments, 1)

  return function() {
      return _this.apply(context, args)
  }
}

参考资料

https://www.jianshu.com/p/2975c25e4d71

你可能感兴趣的:(js函数柯里化)