关于Function.prototype.call.apply理解

我在阅读《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}


如有其它见解的伙伴欢迎一起探讨
posted @ 2018-05-19 08:47  恰逢青雪  阅读(713)  评论(0编辑  收藏  举报