关于Function.prototype.call.apply(

2018-09-02  本文已影响0人  灯光树影

在函数反柯里化的通用实现中有一种通用实现,代码如下:

/**
   函数反柯里化
   @return {function} 处理后的函数  
*/
function uncurring(){
    var that = this;
    return function(){
        return Function.prototype.call.apply(that, arguments);
    }
} 

一篇文章中看到这样一句话:
如果使用apply(null, arguments),因为null对象没有call方法,会报错。
于是,尝试了一下将代码中的that改成null,发现真的报错:
Uncaught TypeError: Function.prototype.call.apply is not a function。
这里说Function.prototype.call.apply不是一个函数。这让我很疑惑,apply不是让window可以“借用”call方法了吗?为什么还需要window对象本身有call方法?

最后在我的理解中,它的过程应该是这样的:
apply先把Function.prototype.call方法的上下文(作用域)改成了that,再调用call相当于:

// fn是调用uncurring函数的函数
function fn(){
    // 把call放到fn的内部作用域中
    var call = function(){
        // native code
    }
    // 调用call方法
    call(arguments[0], arguments[1], ..., arguments[n]);
}   

由于调用call的this被改变成that(即fn),相当于:
apply改变的this其实是改变了调用call的对象

fn.call(arguments[0], arguments[1], ..., arguments[n]);

然后才在调用call后改变fn的上下文,最后相当于:

arguments[0].fn(arguments[1], ..., arguments[n]);

如果把反柯里化函数中的apply(that)改成apply(null)就相当于存在这样的调用:

window.call(arguments[0], arguments[1], ..., arguments[n]);

而window本身并没有call方法,所以报错。

上一篇下一篇

猜你喜欢

热点阅读