---
# System prepended metadata

title: 克服 JS 奇怪的部分 24. arguments 與 spread
tags: ["JavaScript\_", JavaScript 基礎]

---

### 不厭其煩地說明：

- 那就是每當我們執行一個函數時，就會創建一個作用域環境。

- 那麼 **JavaScript Engine** 為替你設定一些東西：

```js
// variable environment
變數環境，包覆我們的變數

// outer environment 
給予外部環境參考

// 特殊關鍵字 - this
再來就是 this .
```

- 而 this，則會根據函數位置的不同，以及它的呼叫方式指向不同的地方
  - 像是全域物件、或者某個物件的本身。
  - 最後，它還設定了一個「特殊的關鍵字」叫做：**arguments**


### 什麼是 arguments(參數)?

- 傳入函數裡的變數，一種稱呼。

```
arguments 是一個特殊的對象，它代表了一個函數的參數集合。
```

### example:

- 這邊需要注意的是：
  我們在執行函數時，可以先不丟參數，這不會報錯誤。
  - **但這在其他的程式語言來說，是會報錯誤的**。

```js
function greet(firstname, lastname, language) {
  console.log(firstname);
  console.log(lastname);
  console.log(language);
}

greet();

// outputs:
獲得三個 undefined
```
- 在函數宣告時，這三個參數在創造階段也被設定好了(表達式亦然)。
- 在我們宣告好函數以後，JavaScript 首先做的事情就是替這些參數設置好記憶體。
  - 也就是在不宣告變數值的情況，預設也是 `undefined`。

### 我們可以把函數內的 arguments 當作數列來看待：

- 為什麼？看看範例就懂：

```js
const greet = (firstname, lastname, language) => {
  console.log(firstname);
  console.log(lastname);
  console.log(language);
  console.log("-------------");
};

greet();
greet("Tony"); // 當我在輸入在第一個位置上時，我的第一個結果就是 Tony

// 輸出結果：
undefined
undefined
undefined
-------------
Tony
undefined
undefined
-------------
```

### 參數設定預設值，避免顯示 undefined：

```js
const greet = (firstname, lastname, language) => {
  // 亦可設定預設值，必免出現 undefined。
  language = language || "jp";

  console.log(firstname);
  console.log(lastname);
  console.log(language);
  console.log("-------------");
};

greet();
// outputs:
undefined
undefined
jp // 輸出的結果可以回顧 Operator precedence 的概念
-------------
```

### 不需設定的參數 - arguments 關鍵字：


### 使用傳統函數 & 箭頭函數，在參數 arguments 會有不同的反饋：

- **箭頭函數** - 不會有 **arguments** 特殊關鍵字。

```js
const greet = (a, b, c) => {
  console.log(arguments); 
    // 特殊關鍵字，這邊使用 arrow function 的話，會報錯
};

greet();
// outputs:
Uncaught ReferenceError: arguments is not defined
```
- **傳統函數** - 在傳統的函數中，**arguments** 用來訪問所有傳入函數的參數。


- 在不輸入參數的情況下，這個特殊關鍵字也會回傳包含原先所設定好的參數。

```js
function greet(a, b, c) {
  console.log(arguments);
}

greet();
// outputs:
undefined undefined undefined 
Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
```

### arguments 也可以顯示其參數資料長度：

```js
function greet(a, b, c) {
  console.log(a, b, c, arguments);
  console.log(arguments.length); // 3
}
greet(); // 0
greet(1, 2, 3); // 根據你傳入的參數有多少。
```


### 剪頭函數，展開參數：

```js
const greet = (...others) => {
  console.log(others);
};

// 展開參數 - 以陣列的形式
greet("a", "b", "c");

```
