定时器中的 this

前言

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

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)

阅读 214

推荐阅读