> For the complete documentation index, see [llms.txt](https://mistborn.gitbook.io/til-coding/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mistborn.gitbook.io/til-coding/javascript/functions.md).

# Functions

## Function Declaration

只要寫一次就可以重複使用，修改只需修改函式

```javascript
function showMessage() {
  alert( 'Hello everyone!' );
}

showMessage();
showMessage();
```

## Local variables

在函式內宣告的變數只能在函式內使用。

```javascript
function showMessage() {
  let message = "Hello, I'm JavaScript!"; // local variable
  alert( message );
}

showMessage(); // Hello, I'm JavaScript!

alert( message ); // <-- Error! The variable is local to the function
```

## Outer variables

```javascript
let userName = 'John';

function showMessage() {
  userName = "Bob"; // (1) changed the outer variable
  let message = 'Hello, ' + userName;
  alert(message);
}

alert( userName ); // John before the function call

showMessage();

alert( userName ); // Bob, the value was modified by the function
```

```javascript
let userName = 'John';

function showMessage() {
  let userName = "Bob"; // declare a local variable
  let message = 'Hello, ' + userName; // Bob
  alert(message);
}

// the function will create and use its own userName
showMessage();

alert( userName ); // John, unchanged, the function did not access the outer variable
```

## Parameters

```javascript
function showMessage(from, text) {
  from = '*' + from + '*'; // make "from" look nicer
  alert( from + ': ' + text );
}

let from = "Ann";

showMessage(from, "Hello"); // *Ann*: Hello

// the value of "from" is the same, the function modified a local copy
alert( from ); // Ann
```

## Default values

若未帶入參數，值會變成 `undefined`，可以用 = 指定預設值，舊版的 JavaScript 不支持預設值。

```javascript
function showMessage(from, text = "no text given") {
  alert( from + ": " + text );
}

showMessage("Ann"); // Ann: no text given

function showMessage(from, text = anotherFunction()) {
  // anotherFunction() only executed if no text given
  // its result becomes the value of text
}
```

## Returning a value

`return` 可以使用在函式的任何位置，一旦返回值，函式停止執行。

```javascript
function checkAge(age) {
  if (age > 18) {
    return true;
  } else {
    return confirm('Do you have permission from your parents?');
  }
}

let age = prompt('How old are you?', 18);

if ( checkAge(age) ) {
  alert( 'Access granted' );
} else {
  alert( 'Access denied' );
}
```

函示沒有返回值或返回空的值，會返回 `undefined`。

```javascript
function doNothing() { /* empty */ }

alert( doNothing() === undefined ); // true

function doNothing() {
  return;
}

alert( doNothing() === undefined ); // true
```

`return` 不能換行，換行會返回 `undefined`。

```javascript
return
 (some + long + expression + or + whatever * f(a) + f(b))
 
// same
return;
 (some + long + expression + or + whatever * f(a) + f(b))
```

## Naming a function

函式是動作，名子通常是動詞，簡短正確的描述該函式要做的動作；團隊決定前綴動詞的意思；函式只做一件事，不同的功能要拆分成不同函式。

* show 代表顯示東西
* get 返回值
* calc 計算值
* create 創造東西
* check 返回布林值

```javascript
showMessage(..)     // shows a message
getAge(..)          // returns the age (gets it somehow)
calcSum(..)         // calculates a sum and returns the result
createForm(..)      // creates a form (and usually returns it)
checkPermission(..) // checks a permission, returns true/false
```

## Functions == Comments

函式要簡短只做一個功能，如果功能太複雜，要拆成幾個小函式再組合起來。

```javascript
function showPrimes(n) {
  nextPrime: for (let i = 2; i < n; i++) {

    for (let j = 2; j < i; j++) {
      if (i % j == 0) continue nextPrime;
    }

    alert( i ); // a prime
  }
}

// easier test & debug like comment readable
function showPrimes(n) {

  for (let i = 2; i < n; i++) {
    if (!isPrime(i)) continue;

    alert(i);  // a prime
  }
}

function isPrime(n) {
  for (let i = 2; i < n; i++) {
    if ( n % i == 0) return false;
  }
  return true;
}
```
