对于call apply bind 大家的理解好多人的理解可能只是停留在可以改变this的指向上(当然我也是因为害怕忘记主要还是自己掌握的不牢,才写的)
先来一个例子
function
mp() {
}
mp.
prototype = {
name:
'手',
tack
:
function() {
console.
log(
"他用" +
this.
name +
'打我')
}
}
var
xiaoming =
new
mp;
xiaoming.
tack()
//他用手打我
那么问题来了 如果我们有一个对象 不想对它重新定义方法 那么我们可以通过call apply bind 来使用xiaoming的方法
zhangsan = {
name:
'棍子'
}
xiaoming.
tack.
call(
zhangsan);
//他用棍子打我
xiaoming.
tack.
apply(
zhangsan);
//他用棍子打我
xiaoming.
tack.
bind(
zhangsan)();
//他用棍子打我
所以我是这样理解的 call apply bind 都是为了动态改变this出现的
当一个对象没有某个方法的时候 其他对象有这个方法,那么我们可以通过上面的call apply bind 用其他的对象方法来操作
下面我再详细说call apply bind 的具体区别
1 call 与apply的区别:
他们接收的参数不一样
var
a =
1;
var
b =
2;
var
fun =
function(
a,
b){
console.
log(
a+
b)
};
fun.
call(
this,
a,
b)
fun.
apply(
this,[
a,
b])
函数的参数数量是不固定的时候,参数是明确知道数量时用 call 。
而不确定的时候用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来遍历所有的参数。
一般apply第二个参数都是为数组
这里有一个面试题
function
com(
msg){
console.
log(
msg)
}
com(
1);
//1
com(
1,
2)
//1
如果我们想要上述方法在传入多个参数的时候 不失效 怎么做呢
function
com(){
console.
log.
apply(
console,
arguments)
}
com(
1);//1
com(
1,
2)//1,2
补充一点Array.prototype.slice.call 可以将伪数组转化成标准数组Array.prototype.slice.call(arguments)
2 bind的使用 :
根据第一个例子就可以看出来 call apply都是直接调用函数 但是bind需要手动调用
var
obj = {
a:
1,
}
var
fun = {
getItem
:
function() {
return
this.
a
}
}
console.
log(
fun.
getItem.
bind(
obj)());
console.
log(
fun.
getItem.
call(
obj));
console.
log(
fun.
getItem.
apply(
obj));
- apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
- apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
- apply 、 call 、bind 三者都可以利用后续参数传参;
- bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。