# 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;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mistborn.gitbook.io/til-coding/javascript/functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
