作者:Dmitri Pavlutin翻譯:瘋狂的技術宅
原文:https://dmitripavlutin.com/ja...
未經允許嚴禁轉載
使用箭頭語法,你可以定義比函數表達式短的函數。在某些情況下,你可以完全省略:
- 參數括號
(param1, param2)
-
return
關鍵字 - 甚至大括號
{ }
。
下面就讓我們來探討一下如何使箭頭函數簡潔明瞭、易於閱讀。另外你會發現一些需要注意的棘手情況,。
1. 基本語法
完整版本的箭頭函數聲明包括:
- 一對帶有參數枚舉的括號
(param1, param2)
- 後面跟隨箭頭
=>
- 以函數體
{FunctionBody}
結尾
典型的箭頭函數如下所示:
const sayMessage = (what, who) => {
return `${what}, ${who}!`;
};
sayMessage('Hello', 'World'); // => 'Hello, World!'
這裏有一點需要注意:你不能在參數 (param1, param2)
和箭頭 =>
之間放置換行符。
接下來我們看看如何縮短箭頭函數,在處理回調時,使它更易於閱讀。
2. 減少參數括號
以下函數 greet
只有一個參數:
const greet = (who) => {
return `${who}, Welcome!`
};
greet('Aliens'); // => "Aliens, Welcome!"
greet
箭頭函數只有一個參數 who
。該參數被包裝在一對圓括號(who)
中。
當箭頭函數只有一個參數時,可以省略參數括號。
可以利用這種性質來簡化 greet
:
const greetNoParentheses = who => {
return `${who}, Welcome!`
};
greetNoParentheses('Aliens'); // => "Aliens, Welcome!"
新版本的箭頭函數 greetNoParentheses
在其單個參數 who
的兩邊沒有括號。少兩個字符:不過仍然是一個勝利。
儘管這種簡化很容易掌握,但是在必須保留括號的情況下也有一些例外。讓我們看看這些例外。
2.1 注意默認參數
如果箭頭函數有一個帶有默認值的參數,則必須保留括號。
const greetDefParam = (who = 'Martians') => {
return `${who}, Welcome!`
};
greetDefParam(); // => "Martians, Welcome!"
參數 who
的默認值爲 Martians
。在這種情況下,必須將一對括號放在單個參數(who ='Martians')
周圍。
2.2 注意參數解構
你還必須將括號括在已解構的參數周圍:
const greetDestruct = ({ who }) => {
return `${who}, Welcome!`;
};
const race = {
planet: 'Jupiter',
who: 'Jupiterians'
};
greetDestruct(race); // => "Jupiterians, Welcome!"
該函數的唯一參數使用解構 {who}
來訪問對象的屬性 who
。這時必須將解構式用括號括起來:({who {}})
。
2.3 無參數
當函數沒有參數時,也需要括號:
const greetEveryone = () => {
return 'Everyone, Welcome!';
}
greetEveryone(); // => "Everyone, Welcome!"
greetEveryone
沒有任何參數。保留參數括號 ()
。
3. 減少花括號和 return
當箭頭函數主體內僅包含一個表達式時,可以去掉花括號 {}
和 return
關鍵字。
不必擔心會忽略 return
,因爲箭頭函數會隱式返回表達式評估結果。
這是我最喜歡的箭頭函數語法的簡化形式。
沒有花括號 {}
和 return
的 greetConcise
函數:
const greetConcise = who => `${who}, Welcome!`;
greetConcise('Friends'); // => "Friends, Welcome!"
greetConcise
是箭頭函數語法的最短版本。即使沒有 return
,也會隱式返回 $ {who},Welcome!
表達式。
3.1 注意對象文字
當使用最短的箭頭函數語法並返回對象文字時,可能會遇到意外的結果。
讓我們看看這時下會發生些什麼事:
const greetObject = who => { message: `${who}, Welcome!` };
greetObject('Klingons'); // => undefined
期望 greetObject
返回一個對象,它實際上返回 undefined
。
問題在於 JavaScript 將大括號 {}
解釋爲函數體定界符,而不是對象文字。 message:
被解釋爲標籤標識符,而不是屬性。
要使該函數返回一個對象,請將對象文字包裝在一對括號中:
const greetObject = who => ({ message: `${who}, Welcome!` });
greetObject('Klingons'); // => { message: `Klingons, Welcome!` }
({ message: `${who}, Welcome!` })
是一個表達式。現在 JavaScript 將其視爲包含對象文字的表達式。
4.粗箭頭方法
類字段提案(截至2019年8月,第3階段)向類中引入了粗箭頭方法語法。這種方法中的 this
總是綁定到類實例上。
讓我們定義一個包含粗箭頭方法的 Greet
類:
class Greet {
constructor(what) {
this.what = what;
}
getMessage = (who) => {
return `${who}, ${this.what}!`;
}
}
const welcome = new Greet('Welcome');
welcome.getMessage('Romulans'); // => 'Romulans, Welcome!'
getMessage
是 Greet
類中的一個方法,使用粗箭頭語法定義。 getMessage
方法中的 this
始終綁定到類實例。
你可以編寫簡潔的粗箭頭方法嗎?是的你可以!
讓我們簡化 getMessage
方法:
class Greet {
constructor(what) {
this.what = what;
}
getMessage = who => `${who}, ${this.what}!`
}
const welcome = new Greet('Welcome');
welcome.getMessage('Romulans'); // => 'Romulans, Welcome!'
getMessage = who => `${who}, ${this.what}!
是一個簡潔的粗箭頭方法定義。省略了其單個參數 who
周圍的一對括號,以及大括號 {}
和 return
關鍵字。
5. 簡潔並不總是意味着可讀性好
我喜歡簡潔的箭頭函數,可以立即展示該函數的功能。
const numbers = [1, 4, 5];
numbers.map(x => x * 2); // => [2, 8, 10]
x => x * 2
很容易暗示一個將數字乘以 2
的函數。
儘管需要儘可能的使用短語法,但是必須明智地使用它。否則你可能會遇到可讀性問題,尤其是在多個嵌套的簡潔箭頭函數的情況下。
我更喜歡可讀性而不是簡潔,因此有時我會故意保留大括號和 return
關鍵字。
讓我們定義一個簡潔的工廠函數:
const multiplyFactory = m => x => x * m;
const double = multiplyFactory(2);
double(5); // => 10
雖然 multiplyFactory
很短,但是乍一看可能很難理解它的作用。
這時我會避免使用最短的語法,並使函數定義更長一些:
const multiplyFactory = m => {
return x => x * m;
};
const double = multiplyFactory(2);
double(5); // => 10
在較長的形式中,multiplyFactory
更易於理解,它返回箭頭函數。
無論如何,你都可能會進行嘗試。但我建議你將可讀性放在簡潔性之前。
6. 結論
箭頭函數以提供簡短定義的能力而聞名。
使用上面介紹的訣竅,可以通過刪除參數括號、花括號或 return
關鍵字來縮短箭頭函數。
你可以將這些訣竅與粗箭頭方法放在一起使用。
簡潔是好的,只要它能夠增加可讀性即可。如果你有許多嵌套的箭頭函數,最好避免使用最短的形式。
本文首發微信公衆號:前端先鋒
歡迎掃描二維碼關注公衆號,每天都給你推送新鮮的前端技術文章
歡迎繼續閱讀本專欄其它高贊文章:
- 深入理解Shadow DOM v1
- 一步步教你用 WebVR 實現虛擬現實遊戲
- 13個幫你提高開發效率的現代CSS框架
- 快速上手BootstrapVue
- JavaScript引擎是如何工作的?從調用棧到Promise你需要知道的一切
- WebSocket實戰:在 Node 和 React 之間進行實時通信
- 關於 Git 的 20 個面試題
- 深入解析 Node.js 的 console.log
- Node.js 究竟是什麼?
- 30分鐘用Node.js構建一個API服務器
- Javascript的對象拷貝
- 程序員30歲前月薪達不到30K,該何去何從
- 14個最好的 JavaScript 數據可視化庫
- 8 個給前端的頂級 VS Code 擴展插件
- Node.js 多線程完全指南
- 把HTML轉成PDF的4個方案及實現