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方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加,这是它们的区别,根据自己的实际情况来选择使用。