一句話明白箭頭函數(shù)中的this

關(guān)于箭頭函數(shù)中this值的問題,網(wǎng)上查查,會告訴你 “箭頭函數(shù)的this固定化,箭頭函數(shù)中的this綁定定義時所在的作用域......”,好繞!

箭頭函數(shù)中this倒底指向誰?一句話,箭頭函數(shù)內(nèi)的this就是箭頭函數(shù)外的那個this! 為什么?因?yàn)榧^函數(shù)沒有自己的this。

如果你已明白這句話的意思,那么本文到此結(jié)束,你可以去看看別的更有營養(yǎng)的東西了。
如果我這句話描述的不清楚,或你對它有懷疑,請繼續(xù)往下看。如果說錯了請使勁拍磚。
查看原文
直接上代碼!

注:以下代碼全基于瀏覽器非嚴(yán)格模式運(yùn)行,且假定你已經(jīng)對非箭頭函數(shù)中的this全然了解

咱先定義一個全局變量a,后面所有的示例都假定此全局變量已存在:

var a = 0;

第一個示例:

// demo1
var obj =  {
  a: 1,
  b1: this.a,
  b2: () => this.a,
};

console.log(obj.b1);  // 0
console.log(obj.b2());  // 0

根據(jù)結(jié)果可以看到obj對象中的屬性b1的值來自全局變量a,而不是obj對象的屬性a,也就是說b1: this.a,中的this指向window。而b2: () => this.a,中的this同樣指向window,返回全局變量a的值。

第二個示例:

// demo2
(function fn(){
  var a = 2;
  console.log(this.a);  // 0

  const subf = ()=>this.a;
  console.log(subf()); // 0
})()

第三個示例:

// demo3
var obj2 =  {
  a: 3,
  b1: function(){ return this.a;},
  b2: function(){ return ()=>this.a},
};
console.log(obj2.b1());  // 3
console.log(obj2.b2()());  // 3

這個示例中箭頭函數(shù)外的this是哪個?我們在箭頭函數(shù)外面加個this.a看看:

var obj2 =  {
  a: 3,
  b1: function(){ return this.a;},
  b2: function(){ return this.a,()=>this.a},
};
console.log(obj2.b1());  // 3
console.log(obj2.b2()());  // 3

第四個示例:

// demo4
var obj3 =  {
  a: 4,
  b1: function(){ return this.a;},
  b2: function(){ return ()=> () => () => this.a},
};
console.log(obj4.b1());  // 4
console.log(obj4.b2()()()());  // 4

這里箭頭函數(shù)返回箭頭函數(shù)再返回箭頭函數(shù),最后一個箭頭函數(shù)返回this.a。這個this是誰?就是最后箭頭函數(shù)外面的外面的外面的那個this,也就是obj3.b1中的那個this,也就是obj3.a。:)
實(shí)情是這樣:箭頭函數(shù)沒有自己的this,所以不管嵌套多少層,都不影響this是誰。

第五個示例:

// demo5
function f0() {
  var a = 5;

  setTimeout(function() {
    var b1 = this.a;
    console.log(b1);  // 0
  }, 100);

  setTimeout(function() {
    var b2 = ()=> this.a;
    console.log(b2());  // 0
  }, 200);
}

f0(); // 0  0

我們都知道setTimeout中的那個function運(yùn)行于全局環(huán)境下,因此里面的this指向window。而箭頭函數(shù)沒有自己的this,所以第二個setTimeout中箭頭函數(shù)的this也指向window.

那么setTimeout的第一個參數(shù)使用箭頭函數(shù)會是個什么情況?看下一個示例。

第六個示例:

// demo6
function f1() {
  console.log(this.a); 
  setTimeout(() => {
    console.log(this.a);  
  }, 100);
}
f1(); // 0  0

這里箭頭函數(shù)作為setTimeout的第一個參數(shù),箭頭函數(shù)外面的那個this是誰?把箭頭函數(shù)換成this.fn()

function f1() {
  console.log(this.a); // 0
  setTimeout(this.fn() , 100); 
}

我們這里不用了解this.fn()有什么功能,看到它我們就會明白了this.fn()中的this和前面一行中的this.a中的this是同一個this。

擴(kuò)展一下:

// 這樣執(zhí)行
f1.call({a: 7});  // 7  7

結(jié)果是輸出兩個7,
為什么?

// demo6
function f1() {
  console.log(this.a);   // 因?yàn)橥ㄟ^call對this的綁定,f1中的this指向 {a: 7}
  setTimeout(() => {
    console.log(this.a);  // 同樣這里this指向 {a: 7}
  }, 100);
}

同理:

var bindf1 = f1.bind({a: 8}); 
bindf1(); // 8 8

總結(jié)

箭頭函數(shù)沒有自己的this,箭頭函數(shù)中用this和普通語句中的this沒什么區(qū)別,所以,你知道非箭頭函數(shù)下怎么用this,就知道箭頭函數(shù)下怎么用this。
關(guān)于 “箭頭函數(shù)對this固定化,箭頭函數(shù)中的this綁定定義時所在的作用域,箭頭函數(shù)不能通過 call() 或 apply() 方法綁定this” 等描述,都源于箭頭函數(shù)沒有自己的this。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 普通函數(shù)中的this: this總是代表它的直接調(diào)用者(js的this是執(zhí)行上下文), 例如 obj.func ,...
    紫陌蘭溪閱讀 1,967評論 1 0
  • 葡萄藤PPT JS中this的指向 大家好,我是IT修真院鄭州分院第6期的學(xué)員王棟,一枚正直、純潔、善良的前端程序...
    17064閱讀 690評論 0 2
  • 箭頭函數(shù)與傳統(tǒng)JavaScript的不同 先來談?wù)凟S5中的this 在ES5中,每個函數(shù)在被調(diào)用時都會自動取得t...
    打鐵大師閱讀 1,398評論 4 21
  • 和小伙伴們再次回到學(xué)校的時候,心里有什么想法也沒有,只是覺得看到大家熟悉又陌生的臉,覺得開心不已。我們漫步在學(xué)校的...
    皮卡是只貓閱讀 169評論 0 0
  • 曾經(jīng)一段時間我很喜歡咪蒙和她的文字。筆鋒犀利,讀來大快人心,描述感同身受,是個努力拼搏傳遞正能量不矯情的姑娘。她最...
    日斤同閱讀 754評論 0 0

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