this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁
情况1:
function a(){
console.log(this); //Window
}
a();
没有明确隶属对象的函数,被直接执行,一般都是window(默认绑定this)
情况2:
let obj = {
name:"admin",
show:function(){
console.log(this) // obj
}
}
obj.show();
有所属对象的函数,被执行,一般是当前函数的所属对象(隐式绑定this)
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
o.b.fn();
如果一个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
情况3:
let obj = {
// show:function(){
// console.log(this)
// }
// }
// setTimeout(obj.show, 1000);
不管这个函数时谁的,有没有所属对象,只要作为参数传递,通过参数执行这个函数,一般情况下都是window (隐式丢失)
但是要注意:不是所有的回调函数中的this都指向window,某些特殊情况下,被系统修改了:
document.addEventListener("click",function(){
console.log(this) //document
})
obox.addEventListener("click",function(){
console.log(this) //obox
})
情况4:
function Fn(){
this.user = "张三";
}
var a = new Fn();
console.log(a.user); //张三
new绑定,函数被new执行后,函数内部的this会指向new出来的实例。
那么如何自行改变this的指向呢:
- call方法改变this指向的使用方式:
var a = {
user:"张三",
fn:function(){
console.log(this.user); //张三
}
}
var b = a.fn;
b.call(a);
通过在call方法,给第一个参数添加要把b添加到哪个环境中,this就会指向那个对象。
2. apply方法改变this指向的使用方式:
var a = {
user:"张三",
fn:function(e,ee){
console.log(this.user); //张三
console.log(e+ee); //11
}
}
var b = a.fn;
b.apply(a,[10,1]);
apply方法和call方法有些相似,但是不同的是,第二个参数必须是一个数组,这个数组中所有的数据,被自动展开之后,传入了原函数
- bind方法改变this指向的使用方式:
var a = {
user:"张三",
fn:function(e,d,f){
console.log(this.user); //张三
console.log(e,d,f); //10 1 2
}
}
var b = a.fn;
var c = b.bind(a,10);
c(1,2);
bind方法和call、apply方法有些不同,bind方法返回的是一个修改过后的函数,bind也可以有多个参数,并且参数可以执行的时候再次添加。
call和apply会自动执行,执行之后的返回值是原函数的返回值,bind执行之后,会得到一个新函数,可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加。