# 筆記_重新認識JS:Day17函式裡的「參數」\(下)_函式裡的參數
----
###### tags: `javascript`
Javascrip 是弱型別語言
不像C# 如果傳入function中參數的數量或型別錯誤就會error
函式的參數
之前我們說過,當我們呼叫一個函式的時候,可以透過「函式名稱」加上「小括號」的方式呼叫。 而小括號內的資料,就是「參數」。
```javascript=
var plus = function (numA, numB) {
return numA + numB;
};
plus(1, 2); // 3
plus(3, 4); // 7
```
像上面這樣,呼叫 `plus(1, 2)` ,其中的 1, 2 作為參數傳至 plus 這個 function,這時 numA 與 numB 內的值就會分別是 1 與 2。
於是,回傳的內容 `numA + numB` 自然就會是 1 + 2 的結果了。
然而,即便我們定義函式時有指定「參數的數量」(如上面範例,分別為 numA 與 numB),但是在呼叫的時候,並不會針對代入的參數數量做檢查。
也就是說,呼叫 `plus` 你可以寫成:
```javascript=
plus(1, 2, 3, 4, 5);
```
或是
```javascript=
plus( );
```
在 JavaScript 都是合法的,只不過在沒有傳入值作為參數的情況下,那些沒有指定的參數預設會是 undefined。 而多傳入的那些參數,在「大部分」情況下是沒有意義的。
既然我說了「大部分」那就代表還是可以拿得到的。
## arguments 物件
事實上,當函式被呼叫的時候,會產生一個 `arguments` 物件。 而這個 `arguments` 物件的內容,其實就是我們呼叫函式所代入的「參數」。
以剛剛的 plus 作為範例:
```javascript=
plus(1, 2, 3, 4, 5);
```
很明顯我們代入的參數數量超過了先前定義好的參數數量,那麼多餘的 3, 4, 5 我們有辦法可以取得嗎?
可以,就透過 arguments 這個物件。
```javascript=
var plus = function (numA, numB) {
console.log( arguments.length );
return numA + numB;
};
// 因為有 5 個參數,會先 log 出 5,然後回傳 1+2 的結果
plus(1, 2, 3, 4, 5);
```
請注意, `arguments` 雖然看起來像個「陣列」,但實際上他只是個帶有「索引」特性的物件,然後內建個 `length` 屬性,其他地方與「陣列」完全不同,當然也沒有 ``.map()`` 或 ``.filter()`` 這些陣列才有的方法。 [註1]
所以說,即便在定義函式的時候完全沒有指定參數給它,我們仍然可以在函式內透過 `arguments` 來取得參數。
```javascript=
var plus = function (numA, numB) {
for( var i = 0; i < arguments.length; i++ ){
console.log( arguments[i] );
}
return numA + numB;
};
// console.log 印出 1 2 3 4 5
plus(1, 2, 3, 4, 5);
```
除此之外, `arguments` 物件還有另一個屬性: `callee`,指的是目前執行的函式。
```javascript=
var plus = function (numA, numB) {
// arguments.callee 指的是 plus 這個 function
console.log( arguments.callee );
return numA + numB;
};
```
當我們需要在函式執行「遞迴」 (在函式內自我呼叫) 時,可以執行 `arguments.callee()`來達成,這屬性在「匿名函式」時特別有用。 但要小心的是,在「嚴格模式」下不允許存取 `arguments.caller` 和 `arguments.callee` 這兩個屬性。
另外, ES6 的箭頭函式 (Arrow Function) 也沒有提供 arguments 物件。
## 以「物件」作為參數
## 參數的預設檢查