前言
call 和 apply 都是为了改变某个函数运行时的 context (即上下文)而存在的,通俗讲就是为了改变函数体内部 this 的指向。
二者的作用完全一样,只是接受参数的方式不太一样。
正题
本人经常记不住call和apply后面的除了第一个参数的格式,今天忽然想到一个方法:
apply第二个参数是数组,数组是array,和apply同一个字母开头,这样岂不是不就好记多了。
剩下的call,自然就是多个参数逗号分割的形式。
484有点聪明?哈哈哈(笑的像个200斤的孩子)。
温故而知新,可以为师也。下面就看道经典题目:
Function.prototype.call.apply(function(a){return a;},[0,1,2])
没看过的童鞋第一眼是不是有点懵逼?反正我是有点的……又是call又是apply的,确定题目没错?
经过各方资料加上自己的理解后整理如下:
Function.prototype.call的call方法是Function原型的方法(见Function.prototype.call),而Function原型是什么呢?其实就是一个函数对象:
ƒ () { [native code] }
把Function.prototype看成一个整体,记为f1;
把Function.prototype.call看成一个稍大的整体,记为f2,那么f2=f1.call;
函数function(a){return a;} 记为f3;
那么上述题目可以简写为:f2.apply(f3,[0,1,2]) ;
将这行代码翻译下,即为:f3.call(0,1,2) 此处可能有人不太懂?
没关系,看个例子:
var foo = {
name:"mingming",
logName:function(){
console.log(this.name);
}
}
var bar={
name:"xiaowang"
};
foo.logName.apply(bar);
foo.logName.apply(bar) 是否可以翻译为bar.logName()呢?(理想bar的执行状态),那么foo这个对象就被替换掉了。
因此,f2.apply(f3,[0,1,2]) 可以翻译为f3.call(0,1,2),即
(function(a){return a;}).call(0,1,2)
第一个参数为1,即return 1。