前言
this 指向问题一直是一个让新手很困扰的问题,这篇文章着重讲 含有定时器时 this 的指向
问题。
关于不包含定时器的 this 指向,这篇文章讲的很清楚,看完之后相信能使小白茅塞顿开超级传送门。
话不多说,开始!
个人理解
- 普通函数:this 的最终指向调用它的对象
- 箭头函数:this 是在定义函数的时候绑定,而不是在执行函数的时候绑定,也不可以
bind(this)
。(或者由内而外寻找:可以改变 this 指向的函数的this
为箭头函数的this
(如:function(){}
),如果没有,则为全局作用域的 this)
开胃菜
let obj={
a:222,
fn: function() {setTimeout(function(){console.log('fn', this)})
},
fn0: function() {console.log('fn0', this);
},
fn1: () => {console.log('fn1', this);
},
fn2: function() {setTimeout(() => {console.log('fn2', this, this.a)})
}
};
obj.fn(); // window
obj.fn0();// {a: 222, fn: ƒ, fn0: ƒ, fn1: ƒ, fn2: ƒ}
obj.fn1();// window
obj.fn2();// {a: 222, fn: ƒ, fn0: ƒ, fn1: ƒ, fn2: ƒ}
分析
- fn 指向 window
setTimeout()
等同于 window.setTimeout()
。普通函数 this 的指向是:谁调用指向谁,fn
里面的 function 是通过 setTimeout()
调用的,所以 this 指向window
- fn0 指向 obj
fn0
是 obj.fn0()
调用的,所以 fn0
的 this 指向 obj
- fn1 指向 window
官方解释:箭头函数的 this 指向定义时所在的 this。
我的理解:由内而外寻找:可以改变 this 指向的函数的 this
为箭头函数的this
。如:function(){}
套用理解:fn1()
->obj.fn1()
。没有可以改变 this 指向的函数,则为全局作用域的 this
- fn2 指向 obj
套用理解:fn2
->window.setTimeout()
(没有可改变 this 指向的函数)->function() {}
(改变 this 指向,查找谁调用了函数)->obj.fn2()
(obj 调用函数,this 指向 obj)
普通函数
const obj = {
num: 10,
hello: function () {console.log(this);
setTimeout(function() {console.log(this);
});
},
outf: outFun
}
function outFun() {console.log('outFun', this); // obj
setTimeout(function() {console.log('outFun', this); // window
});
setTimeout(() => {console.log('outFun', this); // obj
});
}
obj.hello();
obj.outf();
分析
- 第一个 this 指向 obj
普通函数:谁调用指向谁。outfun
是由 obj.outf()
调用的,所以指向 obj
- 第二个 this 指向 window
function()
->window.setTimeout()
,函数是由 window 调用的,所以指向 window
- 第三个 this 指向 obj
()=>{}
(向外寻找)->window.setTimeout()
(没有可改变 this 指向的函数)->outFun()
(改变 this 指向,查找谁调用了函数)->obj.outf()
(obj 调用函数,this 指向 obj)
箭头函数
const obj = {
num: 10,
hello: function () {console.log(this);
setTimeout(function() {console.log(this);
});
},
outf: outFun
}
const outFun = () => {console.log('outFun', this); // window
setTimeout(function() {console.log('outFun', this); // window
});
setTimeout(() => {console.log('outFun', this); // window
});
}
obj.hello();
obj.outf();
分析
outFun
->obj.outf()
(没有可以改变 this 指向的函数,this 指向全局作用域的 this)