前言

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(); // windowobj.fn0();// {a: 222, fn: ƒ, fn0: ƒ, fn1: ƒ, fn2: ƒ}obj.fn1();// windowobj.fn2();// {a: 222, fn: ƒ, fn0: ƒ, fn1: ƒ, fn2: ƒ}

分析

  • fn指向window

setTimeout()等同于window.setTimeout()。普通函数this的指向是:谁调用指向谁,fn里面的function是通过setTimeout()调用的,所以this指向window

  • fn0指向obj

fn0obj.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)