关于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方法,所以报错。