我在阅读《JavaScript设计模式与开发实践》一书时发现一段有趣的代码,他是函数反柯里化uncurry的一种实现方法
uncurrying 函数
var obj = {
"length":1,
"0":1
}
Function.prototype.uncurrying = function() {
var self = this;
return function() {
return Function.prototype.call.apply(self, arguments);
}
}
var push = Array.prototype.push.uncurrying()
push(obj, 2) //{0: 1, 1: 2, length: 2}
可以看到最终执行Array.prototype.push方法的对象是我们传入的obj对象 它成功的通过一个uncurrying后的push方法借用了Array.prototype.push这方法将2新增进来,下面进行重要语句解析
Function.prototype.call.apply(self, arguments)
举个栗子:
我们平时借用Math.Max时求数组中最大值是这样的
Math.Max.apply([], [1,2,3])
- 先执行apply将Math替换为[]
- 然后再执行Max并传入[1,2,3] 因为apply的关系 参数[1,2,3]已经扁平化成1,2,3
- 所以相当于[].Max(1,2,3)
call也是一样的道理:
之所以要和大家讲这个例子是想说明先调用apply再调用排在apply之前的函数max
这次主角也不例外
过程解析:
Function.prototype.call.apply(Array.prototype.push, [obj, 2])
apply替换执行函数的对象并扁平化了数组内容,
Array.prototype.push.call(obj, 2)
call函数将数组内容的第一个参数替换执行函数对象
obj.push(2)
结果便是
{0: 1, 1: 2, length: 2}