我在阅读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}
来源: http://www.jianshu.com/p/789eaff7eaf7