js中call,apply,bind方法

105 阅读2分钟

js的这三个方法是用来改变this的指向,为什么要用到它们,如下

var obj = {
    num : 1,
    fun : function () {
        console.log(this.num); 
    }
}
var a = obj.fun;
a()     // undefined
obj.fun()  // 1

为什么直接执行是可以获取变量值,重新赋值后就不可以了呢,这是因为重新赋值后this的指向改变了,改为指向调用它的对象了,详细请看这里(juejin.cn/post/697331…)

虽然我们可以直接执行来获取到值,但是有时候我们必须要把对象赋值给另外一个变量来保存,那么我们就可以用到下面这几种方法

1、call()

var obj = {
    num : 1,
    fun : function () {
        console.log(this.num); 
    }
}
var a = obj.fun;
a.call(obj)     // 1

通过call方法,就轻易的把obj的this指向给了a,是不是很方便呢?

call()方法除了第一个参数,还可以添加多个参数,如下

var obj = {
    num : 1,
    fun : function (x,y) {
        console.log(this.num); // 1
        console.log(x+y);      // 5
    }
}
var a = obj.fun;
a.call(obj,2,3)     

2、apply() apply()与call()方法很类似

var obj = {
    num : 1,
    fun : function () {
        console.log(this.num); 
    }
}
var a = obj.fun;
a.apply(obj)     // 1

也可以传递多个参数,区别在于第二个参数必须是数组

var obj = {
    num : 1,
    fun : function (x,y) {
        console.log(this.num); // 1
        console.log(x+y);      // 5
    }
}
var a = obj.fun;
a.apply(obj,[2,3])     

或者

var obj = {
    num : 1,
    fun : function (x,y) {
        console.log(this.num); // 1
        console.log(x+y);      // 5
    }
}
var a = obj.fun;
var b = [2,3];
a.apply(obj,b)     

如果call()和apply()的第一个参数是null,则this指向window对象

var obj = {
    num : 1,
    fun : function () {
        console.log(this); 
    }
}
var a = obj.fun;
a.call(null)     // window
a.apply(null)    // window

3、bind() bind()也是改变this的指向,但是又和前面两个有点不同,如下

var obj = {
    num : 1,
    fun : function () {
        console.log(this.num); 
    }
}
var a = obj.fun;
a.bind(obj)

我们发现没有打印结果,是的,实际上bind()返回的是一个修改后的函数,这就是它和前两者的不同

var obj = {
    num : 1,
    fun : function () {
        console.log(this.num); 
    }
}
var a = obj.fun;
var b = a.bind(obj)
console.log(b)  //ƒ () { console.log(this.num); }

同样,bind()也可以传递多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序执行的

var obj = {
    num : 1,
    fun : function (x, y, z) {
        console.log(this.num);  // 1
        console.log(x, y, z);   // 11 12 13
    }
}
var a = obj.fun;
var b = a.bind(obj, 11)
b(12,13)

总结:call和apply都是改变上下文中的this并立即执行这个函数,bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加,这是它们的区别,根据自己的实际情况来选择使用。