先來回顧一下非箭頭函數(shù)的this指向吧
- 指向執(zhí)行時(shí)候的調(diào)用者
const obj = {
name: 'this is obj',
getName(){
console.log('this',this);
}
}
obj.getName()
- 使用嚴(yán)格模式下涩金,不指定調(diào)用者哪痰,會(huì)指向undefined诈唬,不使用嚴(yán)格模式生音,指向window
"use strict"
function testFun() {
console.log('this:',this);
}
testFun()
- 在class中宁否,指向當(dāng)前class
class ClassA{
getName() {
console.log('this',this);
}
}
const classA = new ClassA()
classA.getName()
- 使用apply、call缀遍、bind指向到咱們規(guī)定的obj上
const objA = {
name: 'this is objA'
}
function fnA() {
console.log('this: ',this);
}
fnA.apply(objA)
OK慕匠,再來看下箭頭函數(shù)的this指向,很簡單域醇,記住兩個(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é)合上面說的普通函數(shù)的this指向(第二條)
- 當(dāng)我們執(zhí)行funB()狠角,此時(shí)和fnA一樣,在非嚴(yán)格模式下蚪腋,都是指向window
- 仔細(xì)看fnC()丰歌,這里執(zhí)行的時(shí)候做了手腳,改變了其默認(rèn)的指向(window)屉凯,指向了cObj立帖,不信嗎?看一下fnC的this打印悠砚,的確就是"this is objC"晓勇,沒毛病。
- 此時(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í)再來一個(gè)驗(yàn)證case窿克,把fnD放在任意地方執(zhí)行(為了洗脫上面例子中fnD()是在fnC里面執(zhí)行骏庸,從而導(dǎo)致會(huì)產(chǎn)生歧義的嫌疑),看此時(shí)this究竟是誰年叮。
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等修改指向的序芦。