關(guān)于箭頭函數(shù)中this值的問題,網(wǎng)上查查谐算,會(huì)告訴你 “箭頭函數(shù)的this固定化,箭頭函數(shù)中的this綁定定義時(shí)所在的作用域......”归露,好繞洲脂!
箭頭函數(shù)中this倒底指向誰?一句話剧包,箭頭函數(shù)內(nèi)的this就是箭頭函數(shù)外的那個(gè)this恐锦! 為什么?因?yàn)榧^函數(shù)沒有自己的this疆液。
如果你已明白這句話的意思一铅,那么本文到此結(jié)束,你可以去看看別的更有營(yíng)養(yǎng)的東西了堕油。
如果我這句話描述的不清楚潘飘,或你對(duì)它有懷疑,請(qǐng)繼續(xù)往下看掉缺。如果說錯(cuò)了請(qǐng)使勁拍磚卜录。
查看原文
直接上代碼!
注:以下代碼全基于瀏覽器非嚴(yán)格模式運(yùn)行眶明,且假定你已經(jīng)對(duì)非箭頭函數(shù)中的this全然了解
咱先定義一個(gè)全局變量a艰毒,后面所有的示例都假定此全局變量已存在:
var a = 0;
第一個(gè)示例:
// demo1
var obj = {
a: 1,
b1: this.a,
b2: () => this.a,
};
console.log(obj.b1); // 0
console.log(obj.b2()); // 0
根據(jù)結(jié)果可以看到obj對(duì)象中的屬性b1的值來自全局變量a,而不是obj對(duì)象的屬性a,也就是說b1: this.a,
中的this指向window赘来。而b2: () => this.a,
中的this同樣指向window现喳,返回全局變量a的值凯傲。
第二個(gè)示例:
// demo2
(function fn(){
var a = 2;
console.log(this.a); // 0
const subf = ()=>this.a;
console.log(subf()); // 0
})()
第三個(gè)示例:
// 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
這個(gè)示例中箭頭函數(shù)外的this是哪個(gè)?我們?cè)诩^函數(shù)外面加個(gè)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
第四個(gè)示例:
// 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ù)嗦篱,最后一個(gè)箭頭函數(shù)返回this.a冰单。這個(gè)this是誰?就是最后箭頭函數(shù)外面的外面的外面的那個(gè)this,也就是obj3.b1中的那個(gè)this,也就是obj3.a。:)
實(shí)情是這樣:箭頭函數(shù)沒有自己的this意述,所以不管嵌套多少層,都不影響this是誰荒叼。
第五個(gè)示例:
// 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中的那個(gè)function運(yùn)行于全局環(huán)境下,因此里面的this指向window典鸡。而箭頭函數(shù)沒有自己的this被廓,所以第二個(gè)setTimeout中箭頭函數(shù)的this也指向window.
那么setTimeout的第一個(gè)參數(shù)使用箭頭函數(shù)會(huì)是個(gè)什么情況?看下一個(gè)示例萝玷。
第六個(gè)示例:
// demo6
function f1() {
console.log(this.a);
setTimeout(() => {
console.log(this.a);
}, 100);
}
f1(); // 0 0
這里箭頭函數(shù)作為setTimeout的第一個(gè)參數(shù)嫁乘,箭頭函數(shù)外面的那個(gè)this是誰?把箭頭函數(shù)換成this.fn()
:
function f1() {
console.log(this.a); // 0
setTimeout(this.fn() , 100);
}
我們這里不用了解this.fn()有什么功能,看到它我們就會(huì)明白了this.fn()中的this和前面一行中的this.a中的this是同一個(gè)this球碉。
擴(kuò)展一下:
// 這樣執(zhí)行
f1.call({a: 7}); // 7 7
結(jié)果是輸出兩個(gè)7,
為什么蜓斧?
// demo6
function f1() {
console.log(this.a); // 因?yàn)橥ㄟ^call對(duì)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ù)對(duì)this固定化直奋,箭頭函數(shù)中的this綁定定義時(shí)所在的作用域,箭頭函數(shù)不能通過 call() 或 apply() 方法綁定this” 等描述辽装,都源于箭頭函數(shù)沒有自己的this帮碰。