重載函式 (Function Overloading)

  • 重載函式:讓函式能夠有不同數量的參數。

其實 JavaScript 沒有重載函式的概念,因為 JavaScript 中的函式就是物件,無法像其他程式語言一樣做到重載函式,不過 JavaScript 卻有一級函式的概念,因此也可以做到相似的函式處理。

假設今天有一個 greet 函式,但我不想每次都傳入 language 這個參數,我們可以設定預設值,使用時則傳入不同語言的參數,就能以不同語言來打招呼。

function greet(firstname, lastname, language) {
  language = language || 'en';
  if (language === 'en') {
    console.log(`Hello ${firstname} ${lastname}`);
  }
  if (language === 'es') {
    console.log(`Hola ${firstname} ${lastname}`);
  }
}

greet('Sealman', 'Huang', 'en');
greet('Sealman', 'Huang', 'es');

我們可以再加強以上寫法,使用類似重載函式的寫法,讓函式不用傳入這麼多資訊。

例如:另外創造兩個函式,再將特定的參數值 enes 分別先帶入函式的內容中。
完成後,如果要用英文打招呼就呼叫 greetEnglish 函式,用西班牙語則呼叫 greetSpanish 函式,這樣在使用時就不用考慮 language 這個參數了。

function greetEnglish(firstname, lastname) {
  greet(firstname, lastname, 'en');
}

function greetSpanish(firstname, lastname) {
  greet(firstname, lastname, 'es');
}

greetEnglish('Sealman', 'Huang');
greetSpanish('Sealman', 'Huang');

這種類似重載函式的寫法是一個在 JavaScript 中比較簡單的模式,可以幫助我們更清楚地瞭解每個函式的用途,接下來我們以此為基礎,進階到函式工廠這個設計模式。

函式工廠 (Function Factory)

  • 工廠函式:會回傳一個幫我做事的函式。

工廠函式 makeGreeting 會回傳一個函式給我們,這個函式的邏輯與剛才的 greet 函式相同,只差在參數 language 被移到外部函式。

當內部函式被呼叫時,language 會被包在閉包裡面,它是一個自由變數,內部函式隨著範圍鏈往外找就可以參考到它。

function makeGreeting(language) {
  return function(firstname, lastname) {
    if (language === 'en') {
      console.log(`Hello ${firstname} ${lastname}`);
    }
    if (language === 'es') {
      console.log(`Hola ${firstname} ${lastname}`);
    }
  };
}

var greetEnglish = makeGreeting('en');
var greetSpanish = makeGreeting('es');

greetEnglish('Sealman', 'Huang');
greetSpanish('Sealman', 'Huang');

接著我們執行了兩次 makeGreeting,雖然這是同一個函式(詞彙環境相同),但是執行兩次就會產生兩個不同的執行環境,因此產生的兩個變數 language記憶體位址是不同的。

makeGreeting

這就是閉包的特性,它讓內部函式記得自己是在何時何地被創造的,內部函式可以正確地參考到自己的外部函式的執行環境,也能參考到應該要找的自由變數的記憶體空間位置,一切就好像其他函式的執行環境還沒消失一樣。

使用閉包與函式工廠的概念,我們不用每次都傳入相同的參數,而是直接創造新的函式,透過閉包去製造預設的參數。

回顧

看完這篇文章,我們到底有什麼收穫呢?藉由本文可以理解到…

  • 重載函式的概念以及在 JavaScript 中類似的撰寫模式。
  • 瞭解函式工廠的概念,使用其他函式創造函式。

References