美文网首页
关于Function.prototype.call.apply(

关于Function.prototype.call.apply(

作者: 灯光树影 | 来源:发表于2018-09-02 20: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方法,所以报错。

    相关文章

      网友评论

          本文标题:关于Function.prototype.call.apply(

          本文链接:https://www.haomeiwen.com/subject/lyamwftx.html