今日份:JavaScript高阶函数之uncurrying(反柯里化)

232 阅读1分钟

反柯里化

我们使用JavaScript的时候,经常性的会使用到call,apply,目的是为了去借用其他方法,举个例子:

const person = {
  infofunction(age) {
    return "name:" + this.name + " " + "age:" + age;
  }
}

const person1 = {
  name:"John",
}

person.info.call(person1, 20);

这样的结果就是扩展了相应函数的使用范围,call以及apply是将传入的对象作为this传入某个方法。我们要来说的uncurrying则是把这个过程抽取出来。

我们先看下uncurrying的一个实现方式

Function.prototype.uncurrying = function() {
  let self = this
  return function() {
    let obj = Array.prototype.shift.call(arguments)
    return self.apply(obj, arguments)
  }
}

乍一看,这不是变复杂吗,不急,我们往下看一下效果。

const getType = Object.prototype.toString.uncurrying()

getType('1') //'[object String]'
getType(1) //'[object Number]'

const push = Array.prototype.push.uncurrying()

let val = {
  '0': 1,
  length: 1
}

push(val, 2)

console.log(val)//{ '0': 1, '1': 2, length: 2 }

使用uncurrying,我们可以把Object.prototype.toString.call,Array.prototype.push.call方法变成通用函数,实现别人的函数,为自己的对象使用。

然后我们分析一下uncurrying的实现

Function.prototype.uncurrying = function() {
  let self = this // 保存一下调用uncurrying的环境(例如Object.prototype.toString或者Array.prototype.push)
  return function() {
    let obj = Array.prototype.shift.call(arguments) //截取第一个参数例如('1'或val)
    return self.apply(obj, arguments)//修改this指向并传入剩余参数(Object.prototype.toString.apply('1')或Array.prototype.push.apply(val,2))
  }
}

以上就是反柯里化的相关实现了,在频繁需要修改函数this指向的时候还是可以用一下的。

参考书籍:JavaScript设计模式与开发实践