大白话讲call和aplly
fn.call(obj)就相当于obj.fn(),apply同理。(注意,这里b对象并没有定义a方法,所以这么写只是为了帮助理解,其实是不对的!)
这里的fn是方法,obj是对象,说人话就是:obj对象想要调用fn方法,那obj自己身上或爸爸爷爷身上都没fn方法怎么办呢?那他肯定要去给fn方法打电话,“喂,fn啊,我想喊你来做点事。”怎么样,按中国人的思维你是不是想写成:obj.call(fn),可人家call方法并不是这么实现的,没办法,你只能乖乖写成fn.call(obj)。
说到这,我想你应该要理解一下js中的this。this,汉语翻译是”这“的意思,那”这“是什么呢?细想一下,你是不是经常在方法里面看到this,再细想一下,有this的方法是不是基本上都有个对象去调用它?所以这个this,就是调用它所在的方法的对象~~~~~的引用!(记住,它是一个对象的引用)
可能你想说有的方法没有对象调用,孑然一身,孤零零的就执行了。那我告诉你不存在了,你说没对象调用就没了啊?人家对象偏要隐身你能怎么办?比如说window上面方法setInterval,你调用的时候是不是经常就直接写了,也没喊window对象,但实际的执行过程确实是window去调用的呀,这时候的this就指向window了。
好了,call和aplly毕竟是两个方法,不同之处就在于传参的不同了,想必这点你了解apply和call后,也能轻松理解的。
想想还是举两个例子吧。
比如你写了一个Util类如下:
let Util=function(name){
this.name=name
}
Util.prototype.displayName=funtion(){
console.log(this.name)
}
我们看到,Util原型上面有个展示name的方法。
同时你要处理一个对象obj:
obj={
name:'我是小仙女'
}
这个对象是由字面量创建的,而我们都知道,不论是我们创建的对象obj还是Object,上面都没有displayName方法,这时候我们想要展示obj的name怎么办?
js告诉我们,不要轻易的去改变宿主环境里面的基类,所以我们不推荐在Object的原型上创建一个displayName方法。
怎么办,我们又不想把displayName再重复的写一遍,真是令人着急呀。别怕,这不是有call么。
我想你一定还没忘记我们上面说的乱七八糟的东西吧,那解决办法来了,你要想展示obj的name,完全可以这么做。
Util.prototype.displayName.call(obj)
哈哈哈,其实这里的Util.prototype.displayName就是我前面所说的fn,obj还是那个obj。
至此,本文完,一些细枝末节还是要靠自己意会啦。