定時器中的 this

前言

this指向問題一直是一個讓新手很困擾的問題,這篇文章着重講含有定時器時this的指向問題。segmentfault

關於不包含定時器的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指向windowcode

  • fn0指向obj

fn0obj.fn0()調用的,因此fn0的this指向obj對象

  • fn1指向window

官方解釋:箭頭函數的this指向定義時所在的this。作用域

個人理解:由內而外尋找:能夠改變this指向的函數的this爲箭頭函數的this。如:function(){}get

套用理解:fn1()->obj.fn1()。沒有能夠改變this指向的函數,則爲全局做用域的thisio

  • fn2指向obj

套用理解:fn2->window.setTimeout()(沒有可改變this指向的函數)->function() {}(改變this指向,查找誰調用了函數)->obj.fn2()(obj調用函數,this指向obj)console

普通函數

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()調用的,因此指向objfunction

  • 第二個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)

相關文章
相關標籤/搜索