箭頭函數(shù)的this指向

先來(lái)回顧一下非箭頭函數(shù)的this指向吧

    1. 指向執(zhí)行時(shí)候的調(diào)用者
const obj = {
    name: 'this is obj',
    getName(){
        console.log('this',this);
    }
}
obj.getName() 
    1. 使用嚴(yán)格模式下,不指定調(diào)用者,會(huì)指向undefined,不使用嚴(yán)格模式,指向window
"use strict"
function testFun() {
    console.log('this:',this);
}
testFun()
    1. 在class中,指向當(dāng)前class
class ClassA{
    getName() {
        console.log('this',this);
    }
}

const classA = new ClassA()
classA.getName()
    1. 使用apply、call、bind指向到咱們規(guī)定的obj上
const objA = {
    name: 'this is objA'
}

function fnA() {
    console.log('this: ',this);
}

fnA.apply(objA)

OK,再來(lái)看下箭頭函數(shù)的this指向,很簡(jiǎn)單,記住兩個(gè),首先是

  • 1. 箭頭函數(shù)中的this其實(shí)是定義它時(shí)候的父級(jí)的this

function fnA() {
    // 指向window
    function fnB() {
        console.log('fnB --> this: ',this);
    }
    fnB()
    
    const cObj = {
        name: 'this is objC'
    }
    function fnC() {
        console.log('fnC --> this: ',this);                

        const fnD = () => {
            console.log('fnD --> this',this);
        }
        fnD()
    }
    fnC.apply(cObj)
}
fnA()
運(yùn)行結(jié)果在這里
  • 看,仔細(xì)分析一下代碼,可以看到fnA()在執(zhí)行后,fnA內(nèi)部的this此時(shí)就是window,為什么呢?請(qǐng)結(jié)合上面說(shuō)的普通函數(shù)的this指向(第二條)
  • 當(dāng)我們執(zhí)行funB(),此時(shí)和fnA一樣,在非嚴(yán)格模式下,都是指向window
  • 仔細(xì)看fnC(),這里執(zhí)行的時(shí)候做了手腳,改變了其默認(rèn)的指向(window),指向了cObj,不信嗎?看一下fnC的this打印,的確就是"this is objC",沒(méi)毛病。
  • 此時(shí)看fnD(),在這行這里的時(shí)候,輸出了箭頭函數(shù)fnD內(nèi)部的this,可以看出,內(nèi)部的this是和外部的fnC的this都是指向的objC,但是內(nèi)部和外部的this到底是不是同一個(gè)呢?還是中間被copy了一份新的呢?我們加上下面的代碼:
function fnC() {
        console.log('fnC --> this: ',this);      
        const _fnC_this = this // +++++++

        const fnD = () => {
            console.log('fnD --> this',this);
            console.log('fnD --> this',this === _fnC_this); // +++++++
        }
        fnD()
    }
內(nèi)外部的確是一個(gè)this
  • 此時(shí)再來(lái)一個(gè)驗(yàn)證case,把fnD放在任意地方執(zhí)行(為了洗脫上面例子中fnD()是在fnC里面執(zhí)行,從而導(dǎo)致會(huì)產(chǎn)生歧義的嫌疑),看此時(shí)this究竟是誰(shuí)。
let tempFn
function fnA() {
    // 指向window
    function fnB() {
        console.log('fnB --> this: ',this);
    }
    fnB()
    
    const cObj = {
        name: 'this is objC'
    }
    function fnC() {
        console.log('fnC --> this: ',this);      
        const _fnC_this = this          

        tempFn = () => {
            console.log('fnD --> this',this);
            console.log('fnD --> this',this === _fnC_this);
        }
    }
    fnC.apply(cObj)
}
fnA()
tempFn() // <--- 提出fnD,在外部執(zhí)行
還是上面的效果
  • 還是上面的效果,從而得出:箭頭函數(shù)中的this,是在定義它時(shí)候的父級(jí)的this,而不是執(zhí)行時(shí)候的父級(jí)的this,謹(jǐn)記這一點(diǎn)~
  • 2. 箭頭函數(shù)中的this是不能被apply、call、bind等修改指向的。

  • 為了驗(yàn)證上面的結(jié)論,我們舉個(gè)例子:
function fnA() {
    // 指向window
    function fnB() {
        console.log('fnB --> this: ',this);
    }
    fnB()
    
    const cObj = {
        name: 'this is objC'
    }
    function fnC() {
        console.log('fnC --> this: ',this);      
        const _fnC_this = this      

        const dObj =  {
            name: 'this is objD'
        }

        const fnD = () => {
            console.log('fnD --> this',this);
            console.log('fnD --> this',this === _fnC_this);
        }
        fnD.apply(dObj) // <--- 修改fnD的指向
    }
    fnC.apply(cObj)
}
fnA()
效果還是和上面一樣,并不是指向了我們新的dObj
  • 就很有力得證明了,call、apply、bind是不能修改箭頭函數(shù)的this指向的。

總結(jié)一下

普通函數(shù)的this指向:

  • 1. 指向執(zhí)行時(shí)候的調(diào)用者
  • 2. 使用嚴(yán)格模式下,不指定調(diào)用者,會(huì)指向undefined,不使用嚴(yán)格模式,指向window
  • 3. 在class中,指向當(dāng)前class
  • 4. 使用apply、call、bind指向到咱們規(guī)定的obj上

箭頭函數(shù)的this指向:

  • 1. 箭頭函數(shù)中的this其實(shí)是定義它時(shí)候的父級(jí)的this
  • 2. 箭頭函數(shù)中的this是不能被apply、call、bind等修改指向的。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容