废话不多说,直接上图:
图意为方法的执行处
代码决定this是谁,其执行代码为 object.f()
, 则 f 中的this === object
可能还是不清楚,举个栗子说明:
全局方法中的this
function f(){
return this;
}
f() === window; //true
说明:以上例子执行时,执行f() 相当于window.f() === window,也可以理解为window.f 中的this就是window
对象方法中的this
var obj={
f:function(){
return this
}
}
obj.f() === obj; //true
var f = obj.f;
f() === obj; //false
f() === window; //true
上述例子执行时为 obj.f()
,和我们上面的图片完全吻合,故为obj
而下面执行时为 window.f()
,有力证明了执行环境决定this指向。
进阶例子:
var name='global';
function f(){
console.log(this.global);
}
var obj={
name:'obj的name',
methods:function(){
f();
console.log(this.name);
}
}
obj.methods(); //输出: global obj的name
本例中执行代码为 f(),虽然是在obj.methos内部执行的,但是其实际执行代码依然是标准的object.f()
,所以其中的this为window。
局部/匿名方法中的this
var name='global';
var obj={
name:'obj的name',
methods:function(){
var partialFun=function(){
console.log(this.name)
}
partialFun();
return function(){
console.log(this.name)
}
}
}
obj.methods()(); //输出:global global
匿名和局部函数是特别的函数,他不能通过window.partialFun()来调用,但是默认其函数内部中的this为window对象。
以上所有的例子如果你能理解了,基本已经可以处理大部分this的应用了,但是有时候我想规定这个this必须是谁,这种情况下怎么办呢?
自定义this的指向
bind、apply、call
均可改变this的指向
var name = 'global';
var obj = {
name: 'obj',
f:function(){
return this.name
}
}
obj.f.bind(window)(); //global
f 中的this本来指向obj, 输出 obj,但是由于bind改变其指向为window,所以输出了 global
例:
var name='global'
var obj={
name:'obj的name',
f1:function(){
console.log(this.name)
},
f2:function(){
console.log(this.name)
}.bind(this) //这里的this是window
}
console.log(this); // window
obj.f1(); //输出: obj的name
obj.f2(); //输出: global
还有这样的
obj.f1.apply(this,[]); //global
obj.f1.call(this,''); //global
apply,call是在调用时
改变当前方法中this的指向
bind是在声明时
强制改变方法中this的指向,具有传递性,即其他变量引用此被bind过的方法时,也无法逃避之前绑定的值。
总结: