|
|
|
|
|
箭頭函數(shù)表達(dá)式是使用“胖箭頭”(=>
)語法編寫的匿名函數(shù)表達(dá)式。與傳統(tǒng)函數(shù)不同,箭頭函數(shù)在它們的工作方式上有一些重要的區(qū)別,還有一些語法增強(qiáng)。最大的功能差異是箭頭函數(shù)沒有自己的this
綁定或原型,不能用作構(gòu)造函數(shù)。箭頭函數(shù)也可以寫成比傳統(tǒng)函數(shù)更緊湊的替代方案,因?yàn)樗鼈兛梢允÷詤?shù)周圍的括號(hào),并添加帶有隱式返回的簡(jiǎn)潔函數(shù)體的概念。在本文中,將演示傳統(tǒng)函數(shù)和箭頭函數(shù)如何處理this
,分析它們的不同之處。
箭頭函數(shù)沒有this值
在 JavaScript 中,關(guān)鍵字this
通常被認(rèn)為是一個(gè)棘手的話題。文章詳解JS里this的上下文對(duì)象及用法解釋了this
如何工作,以及this
如何根據(jù)程序是否在全局上下文中使用它、作為對(duì)象中的方法、作為函數(shù)或類的構(gòu)造函數(shù)來隱式指示,或作為DOM事件處理程序。
箭頭函數(shù)有this
語法,這意味著this
的值由周圍的范圍(詞法環(huán)境)決定。
下面一個(gè)示例將演示傳統(tǒng)函數(shù)和箭頭函數(shù)如何處理this
.。
在以下printNumbers
對(duì)象中,有兩個(gè)屬性:phrase
和numbers
。對(duì)象上還有一個(gè)方法loop
,它應(yīng)該打印phrase
字符串和當(dāng)前值numbers
:
const printNumbers = {
phrase: '當(dāng)前值是:',
numbers: [1, 2, 3, 4],
loop() {
this.numbers.forEach(function (number) {
console.log(this.phrase, number)
})
},
}
人們可能期望該loop
函數(shù)在每次迭代時(shí)在循環(huán)中打印字符串和當(dāng)前數(shù)字。但是,在運(yùn)行函數(shù)的結(jié)果中,phrase
實(shí)際上是undefined
:
printNumbers.loop()
這將輸出以下內(nèi)容:
undefined 1
undefined 2
undefined 3
undefined 4
如上所示,this.phrase
是未定義的,表面匿名函數(shù)中的this
傳入forEach
方法沒有引用printNumbers
對(duì)象。這是因?yàn)閭鹘y(tǒng)的函數(shù)this
不會(huì)從環(huán)境的范圍來確定它的值,也就是printNumbers
對(duì)象。
在舊版本的 JavaScript 中,不得不使用bind
顯式設(shè)置this
。
使用bind
改正上面的函數(shù):
const printNumbers = {
phrase: '當(dāng)前值是:',
numbers: [1, 2, 3, 4],
loop() {
// 從printNumbers綁定`this`到內(nèi)部forEach函數(shù)
this.numbers.forEach(
function (number) {
console.log(this.phrase, number)
}.bind(this),
)
},
}
printNumbers.loop()
這將輸出預(yù)期的結(jié)果:
當(dāng)前值是: 1
當(dāng)前值是: 2
當(dāng)前值是: 3
當(dāng)前值是: 4
箭頭函數(shù)可以提供更直接的處理方式。由于它們的this
值是根據(jù)詞法范圍確定的,因此內(nèi)部函數(shù)forEach
可以訪問外部printNumbers
對(duì)象的屬性,如下所示:
const printNumbers = {
phrase: '當(dāng)前值是:',
numbers: [1, 2, 3, 4],
loop() {
this.numbers.forEach((number) => {
console.log(this.phrase, number)
})
},
}
printNumbers.loop()
這將輸出預(yù)期的結(jié)果:
當(dāng)前值是: 1
當(dāng)前值是: 2
當(dāng)前值是: 3
當(dāng)前值是: 4
這些示例表明,在forEach
、map
、filter
和reduce
等內(nèi)置數(shù)組方法中使用箭頭函數(shù)可以更直觀、更易于閱讀,從而使該策略更有可能滿足預(yù)期。
傳統(tǒng)函數(shù)和箭頭函數(shù)處理this值的不同方法
在 JavaScript 中,一個(gè)新函數(shù)定義了它自己的this
值。但是,該this
值并不能直接在匿名函數(shù)內(nèi)部使用。請(qǐng)參見以下示例:
function Car() {
this.speed = 0;
this.speedUp = function (speed) {
this.speed = speed;
setTimeout(function () {
console.log(this.speed);
}, 1000);
};
}
let car = new Car();
car.speedUp(50);
輸出:
undefined
在setTimeout()
函數(shù)的匿名函數(shù)內(nèi)部,this.speed
是undefined,原因是匿名函數(shù)的this
隱藏了speedUp()
方法。
要解決此問題,請(qǐng)將this
值分配給不會(huì)在匿名函數(shù)內(nèi)隱藏的變量,如下所示:
function Car() {
this.speed = 0;
this.speedUp = function (speed) {
this.speed = speed;
let self = this;
setTimeout(function () {
console.log(self.speed);
}, 1000);
};
}
let car = new Car();
car.speedUp(50);
輸出:
50
箭頭函數(shù)能獲取封閉上下文的this值
與匿名函數(shù)不同,箭頭函數(shù)會(huì)捕獲封閉上下文的this
值,而不用創(chuàng)建自己的this
上下文。以下代碼應(yīng)按預(yù)期工作:
function Car() {
this.speed = 0;
this.speedUp = function (speed) {
this.speed = speed;
setTimeout(
() => console.log(this.speed),
1000);
};
}
let car = new Car();
car.speedUp(50);
輸出:
50
總結(jié)
箭頭函數(shù)在許多方面與傳統(tǒng)函數(shù)不同,包括確定其作用域的方式和表達(dá)語法的方式。本文詳細(xì)介紹了JS箭頭函數(shù)=>與傳統(tǒng)匿名函數(shù)處理this
的不同方法,希望看了本文的你,對(duì)箭頭函數(shù)和傳統(tǒng)函數(shù)會(huì)有進(jìn)一步的認(rèn)識(shí)。
參考文章