JavaScript基礎介紹:函式與箭頭函式

Sean Yeh
Web Design Zone
Published in
8 min readApr 1, 2022

--

Banff National Park, Canada, photo by Sean Yeh

什麼是函式?

函式(Function)是一種包裝程式的方式,可以重複使用。它會基於輸入的值執行某些處理程序後,再將結果回傳的機制。也就是說,函式可以接收一個(或數個)值,並把這個值轉換為另外一個結果後回傳。

每個程式語言都有其預定提供的函式,除了預定的函式之外,開發人員可以自行定義函式,這種函式被稱為自定義函式。JavaScript也不例外,除了提供內建函式外,也可以讓開發人員自己定義函式。

函式優點

由於函式具有下面幾項優點,常被廣泛的使用在程式中:

  • 可以重複被呼叫使用,簡化程式的流程
  • 容易對程式進行除錯
  • 寫程式時便於分工合作

定義函式

依照MDN上面的說明:

可以知道自行定義函式有下面幾個方式:

  • 利用function定義
  • 利用Function建構子定義
  • 利用函式常值定義
  • 利用箭頭函式定義

function指令定義

一般來說,最間單最基礎的方式是利用fuction來定義函式,透過這個關鍵字告訴JavaScript接下來要宣告一個函式了。這種方式被稱為function declaration,其語法如下:

function 函式名稱(參數,...) {
...處理程序...
return 傳回值
}

例如下面是一個計算矩形的函式,只要輸入寬度與高度,就可以得到矩形的大小:

function rectArea(width, height) {
return width * height;
}

原則上來說,函式需要一個名稱才可以讓JavaScript來呼叫。然而,在某些情況下可以不需要名稱就可以被執行,這種函式被稱為「匿名函式」。我們留待後面說明。

緊接在函式名稱後面的括號,裡面放的值為參數(parameter)。參數用來表明該函式將要接收的值,就是該函數執行時所需的資料。

傳回值則是函式處理後產生的結果,一般會透過return來決定要回傳的內容是什麼。return指令一般會寫在函式的末端。但是也不是每個函式都需要有傳回值,如果沒有傳回值可以省略return指令不寫,JavaScript會自動幫我們回傳undefine。所以,我們可以把undefine當作函式回傳的預設值。

此外,有些函式僅當作執行某段邏輯為目的而存在,並不需要我們輸入任何的參數值。然而要特別注意的是,即使如此,函式後面的括號仍然不可以省略。

Function建構子(constructor)定義

Function物件為JavaScript的內建物件。基本上來說,每個JavaScript函式都是Function物件。因此,我們也可以透過這個物件來定義函式。

var 變數 = new Function(參數,...,函式處理程序)

可以省略new:

var 變數 = Function(參數,...,函式處理程序)

相對於function指令的定義方式,Function建構子可以使用字串定義參數與函式本體。除此之外,其實未必需要使用這種Function建構子的定義方式。

函式常值定義

除了前面兩種方式外,還可以使用常值定義函式,又稱為function expression(函式表達式)。可以帶入變數或當成參數傳入另一個函式,甚至可作為傳回值回傳。

var 變數 = function(參數,...) {
...處理程序...
return 傳回值
}

例如:

var rectArea = function (width, height) {
return width * height;
}

與function指令定義方式的差異

乍看之下,這個定義方式雖與前面的function指令定義法很像,但還是有下面幾個差異:

# 是否可以在函式前面呼叫函式?

透過function指令定義的函式可以在定義的位置前面呼叫該函式;而使用函式常值定義的函式,則不可以在該定義的位置前面呼叫之,會出現undefine的結果。舉例來說:

//function指令定義的函式rectArea(2,5)function rectArea(width, height) {
return width * height;
}

可以被執行:

但是,下面的程式碼就會出錯。

//function指令定義的函式console.log(rectArea(5, 5));
var rectArea = function (width, height) {
return width * height;
}

#函式定義後記憶體是否回收?

透過function指令定義的函式,只要被定義過後就無法從記憶體中刪除並回收。而使用函式常值定義的函式,則是正常的跟著變數的生命週期運作。可能在定義完畢後直接被回收或是跟著變數的參考被移除時被回收。

函式的執行

寫在函式裡面的程式內容在JavaScript程式剛啟動時並不會被執行。必須經過「呼叫」(invoke)的程序。呼叫函式的方式很簡單,只要在函式名稱後面加上一個小括號就可以了。例如:

函式名稱()
// 或是
函式名稱(參數)

一但函式被呼叫後,就會開始執行函式中的程式區塊,當區塊中的最後一行被執行完畢,該函式就結束工作。如果在執行的過程中,發現了return 的關鍵字,函式就會返回return 的數值。

函式特性

函式有下面幾項特性:

可重複呼叫

函式可以被重複呼叫。例如下面的程式碼,我們就重複呼叫了4次Hello函式。

function Hello(){
alert("Hello World");
}
Hello();
Hello();
Hello();
Hello();

具區域概念

函式除了可以被重複呼叫外,並且具有區域的概念。在 ES6 尚未出現之前,JavaScript 的變數,其最小的有效範圍是以 function 做界線的區隔。函式在尚未被呼叫之前是不會發生作用的。

如下面函式,即使已經將函式放入頁面的<script>中,只要該函式尚未被呼叫,就不會發生任何作用。

function Hello(){
alert("Hello World");
}

我們可以透過Hello(),可以呼叫函式:

function Hello(){
alert("Hello World");
}
Hello()

箭頭函式(Arrow Function)

箭頭函式是ES6新增的一種創造函式的方式。利用這種方式可以簡化函式常值的定義方式。在箭頭函式中不會用到 function 關鍵字。取而代之的是以箭頭( => )連接參數與函式本體。語法如下:

(參數,...)=> { ...函式本體... }

上面的語法雖然已經看起來很簡單了,但依據不同的狀況還可以更加簡化。

假設我們有一個一般的函式:

function (x){
return x * 10;
}

使用箭頭函式來表示的時候可以改成:

(x) => {
return x * 10;
}

在上面的程式裡,我們省略了function關鍵字。

# 函式本體只有單行敘述,可以省略表示區塊的大括號。

(參數,...)=> ...函式本體...

# 函式本體處理後的值即為回傳值,可以省略return指令。例如:

let sum  = (x,y)=> x + y

因此,上面的程式碼可以省略為:

(x) => x * 10;

# 函式只有一個參數時,可以省略中括號

上面的程式碼可以再近一步省略為:

x => x * 10;

如果有兩個以上的參數,就不可以省略,例如下面的程式碼:

// 傳統函式
function (x, y){
return x + y + 20;
}
// 箭頭函式
(x, y) => x + y + 20;

箭頭函式的中括號即不可以省略。

# 若函式沒有任何參數時,不可以省略中括號

例如下面的程式碼:在傳統的函式下,已經沒有任何參數時,在簡化為箭頭函式的時候,就不可以省略中括號。

結語

以上簡單的說明函式的定義、宣告以及呼叫函式的方式。當程式越來越複雜時,程式的維護與除錯的難度就會跟著上升,函式是一個常常被軟體工程師用來簡化程式的一個方式,將程式重複的部分寫成函式,不僅簡化了程式碼,在維護與除錯上也會變得較為清晰方便。因此,學習掌握函式的各項性質與用法,在程式撰寫上便得以更加得心應手。

--

--

Sean Yeh
Web Design Zone

# Taipei, Internet Digital Advertising,透過寫作讓我們回想過去、理解現在並思考未來。並樂於分享,這才是最大贏家。