call、apply和bind都是为了改变函数运行中this的指向,那当中的this又是什么呢
this的指向
var value = '2';
function thisValue(){
console.log(this.value);
}
var obj = {
value:'1',
thisValue:thisValue
}
var obj1 = {
value:'2',
obj:obj
}
obj.thisValue(); //值是1
thisValue(); //值是2
obj1.obj.thisValue();//值是1
再上一段代码中同样是调用thisValue的方法,但是值却不一样,造成这个结果的原因是由于运行环境的不同
- 第一个运行环境在obj对象中,this指的是对象obj。
- 第二个运行环境是全局范围,所以this指的是全局范围内的对象window。
- 第三个虽然是通过obj1调用对象obj中的方法thisValue,但是运行环境仍在obj中,this指的是对象obj
总结:this永远指向一个对象,this的指向却决于函数运行的环境
call()方法
let bf = {
name: "zhangsan",
age: 19
}
function getBf(x, y) {
console.log(x + "," + y);
console.log(this);
console.log(this.name);
}
getBf(4, 5);
//输出结果为
//4,5
//window对象
//
getBf.call(bf, 4, 5);
//输出结果为
//4,5
// {name: "zhangsan", age: 19}
//zhangsan
- 第一种,是在全局范围内运行函数,所以this指的是window对象,由于window对象没有name属性,答应出来的结果为空
- 第二种,使用call方法指定了一个bf对象作为this,所以this指的是bf对象,bf的name值就为zhangsan
apply()方法
apply方法和call方法类似唯一的区别就是,apply传的参数为参数数组,而call传的是参数列表
getBf.call(bf, 4, 5);//call调用
getBf.apply(bf, [4, 5]);//apply调用
bind()方法
bind()与apply(),call()方法的区别是,bind()的返回值为一个函数,且函数无论怎么调用,其this都会指向原来所绑定的对象。
将一个方法从对象中拿出来,然后再调用,期望方法中的 this 是原来的对象。如果不做特殊处理的话,一般会丢失原来的对象。基于这个函数,用原始的对象创建一个绑定函数,巧妙地解决了这个问题
let bf = {
name: "zhangsan",
func:function(){
return this.name
}
}
let obj1 = bf.func
let obj2 = obj1.bind(bf)
obj1()//返回值为空字符串
obj2()//返回值为张三