深入探討 TypeScript 之 Arrow Function
Arrow function 是 ES6 最重要的發明,讓 FRP 能以更簡潔的方式呈現,TypeScript 當然可使用,在 Angular 也隨處可見,如 RxJS 就必須大量使用 arrow function,是學習 Angular 一定要會的。
Version
TypeScript 2.3
以 => 取代 Anonymous Function
Arrow function 可以用來取代 anonymous function。1
2
3
4
5
6
7let hello = function (firstName: string, lastName: string): string {
return `Hello ${firstName} ${lastName}`;
};
message = hello('Sam', 'Xiao');
console.log(message); // Hello Sam Xiao
後面是 anonymous function,但我們可發現,function
事實上是個虛字。
1 | let hello = (firstName: string, lastName: string): string => { |
將 function
省略,改以 =>
取代。
但又發現 return
也是虛字。
1 | let hello = (firstName: string, lastName: string): string => `Hello ${firstName} ${lastName}`; |
因為只有單一 return
,可將 {return}
一起省略。
1 | let hello = (firstName: string): string => `Hello ${firstName}`; |
假如我們只保留 firstName
1 個參數。
1 | let hello = firstName => `Hello ${firstName}`; |
因為只有單一參數,連 ()
都可省略。
以 => 取代 Callback
Arrow function 可以用來取代 callback。
1 | const angular = [ |
如常用的 map()
,會需要我們傳入 callback,決定要回傳的新陣列。
但我們可發現,function
事實上是個虛字。
1 | const angular = [ |
可將 function
省略,改用 =>
。
但又發現 return
也是虛字。
1 | const angular = [ |
因為只有單一 return
,可將 {return}
一起省略。
1 | const angular = [ |
因為只有單一參數,連 ()
都可省略。
語法規則
多參數
1 | (param1, param2, …, paramN) => { statements } |
- 將
function
以=>
取代。 - 若有多行程式,須以
{}
包起來。
1 | (param1, param2, …, paramN) => expression |
- 將
function
以=>
取代。 - 若只有單一
return
,可將{return }
拿掉。
單一參數
1 | (singleParam) => { statements } |
- 將
function
以=>
取代。 - 若有多行程式,須以
{}
包起來。 - 若只有單一
return
,可將{return }
拿掉。 - 單一參數,可連
()
都拿掉。
無參數
1 | () => { statements } |
- 將
function
以=>
取代。 - 若有多行程式,須以
{}
包起來。 - 若只有單一
return
,可將{return }
拿掉。 - 無參數必須保留
()
。
回傳物件
1 | params => ({foo:bar}) |
- 將
function
以=>
取代。 - 多參數/單一參數/無參數的規則依舊。
- 將回傳物件外面加上
()
因為
{}
已經被物件使用,只好改用()
。
Anonymous Function 與 this
在 ES5 時,anonymous function 搭配 this 時,總讓人很糾結。
1 | var Foo ={ |
結果執行錯誤,this.name
為 undefined。
因為 anonymous function 的 this,並不是指向 Foo
,所以存取不到 this.name
。
在 ES5,我們會這用以下寫法:
1 | var Foo ={ |
第 9 行
1 | that = this; |
讓 receive
scope 的 that
指向 this
。
11 行
1 | console.log(that.name); |
改用 that.name
,就可以正確顯示 Hello Sam
。
很多人搞不懂 this 是什麼,就乾脆都寫成 that = this。
Arrow Function 與 this
我們剛剛知道,在ES6 可以使用 arrow function 取代 anonymous function。
1 | var Foo ={ |
使用 arrow function 後,this
就能如預期的抓到 this.name
,顯示 Hello Sam
。
透過 TypeScript Playground,我們來看看到底有什麼黑魔法:
1 | var Foo = { |
第 7 行
1 | var _this = this; |
原來編譯成 ES5 之後,TypeScript 自動幫我們加上 _this = this
,因此我們可以抓到 name
。
雖然 anonymous function 與 arrow function 對 this 的觀點不同,但並沒有誰對誰錯,只是應用場合不同,當你比較需要類似 OOP 的方式,就使用 arrow function;若比較需要 FRP 的方式,就使用 anonymous function,當你手中不再只有錘子,所看的東西就不再只是釘子。
Conclusion
- Arrow function 是 FRP 的重要推手,讓我們可以使用更精簡的方式使用 callback,將更多的虛字拿掉,只留下商業邏輯中最關鍵的部分。
this
一直是 JavaScript 頗具爭議之處,arrow function 讓我們有另外一種方式使用this
,我們可以視需求決定該使用 arrow function 或 anonymous function。
Reference
TypeScript, Handbook : Functions
Egghead.io, Arrow Function => in ES6