### 不厭其煩地說明:
- 那就是每當我們執行一個函數時,就會創建一個作用域環境。
- 那麼 **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");
```