函式

函式 在 JavaScript

6 個練習

關於 函式

函式是一段有組織、可重複使用的程式碼區塊,用來執行某個動作。 在 JavaScript 中,定義函式的方式有好幾種。 這裡我們會介紹_函式宣告_和_函式運算式_。 其他做法,像是箭頭函式,會在其他概念中介紹。

函式宣告

在 JavaScript 中,定義函式的標準做法是_函式宣告_,也稱為_函式定義_或_函式敘述_。

它由 function 關鍵字、函式名稱,以及一串以逗號分隔、包在括號中的參數組成。 接著是包在大括號裡的函式主體(定義函式做什麼的敘述集合)。

function someName(param1, param2, param3) {
  // ...
}

使用函式

在 JavaScript 中,只要寫出函式名稱,後面接著一對包含引數的括號,就能呼叫函式。

someName(arg1, arg2, arg3);

在 JavaScript 中,光是寫出函式名稱並不會呼叫函式。

function sayHello() {
  console.log('Hello, World!');
}

sayHello;
// => [Function: sayHello]
// The text representations varies between environments.

sayHello();
// => 'Hello, World!'

參數

在函式主體中使用參數時,要留意可能對傳入函式的原始值造成副作用。 在 JavaScript 中,引數是原始值參照的複本。 實際上代表什麼意思,取決於引數的資料型態。

  • 原始資料型態的值是_不可變的_。 所有「修改」一律會建立一個新的原始值。 因此,函式主體中對引數做的任何事,都不會影響到原始值。

    const num = 0;
    
    function increase(number) {
      number = number + 1;
    }
    
    increase(num);
    num;
    // => 0
    
  • 像是_物件_、陣列、_函式_這類的值就不一樣。 由於複製的是參照,重新賦值並不會影響原始值。 不過,因為你處理的是淺拷貝,在函式主體中修改引數,也會一併改變傳入的原始值。

    const nums = [0, 1, 2, 3, 4];
    
    function pushFive(arr) {
      arr.push(5);
    }
    
    pushFive(nums);
    nums;
    // => [0, 1, 2, 3, 4, 5]
    

在 JavaScript 中,函式宣告裡定義的所有參數預設都是選用的。 如果呼叫函式時提供的引數比參數少,缺少的引數在函式主體裡會是 undefined,請參閱 Null 與 Undefined。 在許多情況下,如果沒有傳入值,或傳入的是 undefined,用_預設_值初始化參數會更合理。 做法是直接在函式定義中指定預設參數。

function someName(param1 = defaultValue1, param2 = defaultValue2) {
  // ...
}

呼叫函式時傳入的引數可以比函式定義中的參數還多。 所有引數,包括多出來的那些,都能在 arguments「陣列」 裡找到。

也可以定義接受任意數量引數的函式(可變參數函式),詳情請參閱其餘與展開運算子中的其餘參數。

return 敘述

return 敘述會結束函式的執行,並指定一個回傳給函式呼叫者的值。一個函式可以有多個 return 敘述。

function checkNumber(num) {
  if (num === 0) {
    return 'You passed 0, please provide another number.';
  }

  return 'Thanks for passing such a nice number.';
}

一個沒有回傳值、或沒有 return 敘述的函式,其結果是 undefined。 JavaScript 中沒有隱含的 return。

function nakedReturn(a) {
  a * 2;
  return;
}

nakedReturn(1);
// => undefined

function noReturn(a) {
  a * 2;
}

noReturn(1);
// => undefined

在 JavaScript 中,函式只能回傳恰好一個值。 如果想傳遞更多資訊,必須先把它們合併成單一實體,通常是合併成物件或陣列。

function divide(a, b) {
  return {
    quotient: Math.floor(a / b),
    remainder: a % b,
  };
}

函式運算式

函式宣告是一個獨立的敘述。 但有時候,把函式定義成另一個運算式的一部分會更方便,例如用在賦值中、當成函式參數(回呼),或當成物件裡的值。 這可以用函式運算式做到。 它的語法和函式宣告相同,差別在於可以省略函式名稱,建立一個_匿名函式_。

const someFunction = function (param) {
  // ...
};

someOtherFunction(function (param) {
  // ...
});

const obj = {
  someFunction: function (param) {
    // ...
  },
};

作用域

在 JavaScript 中,函式會引入一個新的執行環境。 在函式內定義的變數,在該函式之外無法存取。 但在父作用域(定義函式本身所在的作用域)中定義的變數,在函式內可以存取。 MDN 關於作用域的文件展示了這種行為的範例。

想進一步了解 JavaScript 中的變數作用域,請看看閉包。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟

學習 函式